开发者

struct and array problem in C

开发者 https://www.devze.com 2023-02-19 23:41 出处:网络
Here is the problem: I have a struct like this: struct{ Variable a; Variable 2; char ch[1]; } I need to point ch to another struct containing several char arrays.No, I CAN NOT change开发者_如何转开

Here is the problem:

I have a struct like this:

struct{
    Variable a;
    Variable 2;
    char ch[1];
}

I need to point ch to another struct containing several char arrays. No, I CAN NOT change开发者_如何转开发 the first struct definition at all. I just need some how to put the first byte of my second struct in ch[1] and I simply don't know how to do this. Please help me. Thanks.


You can't "point" an array at something else because an array is not a pointer. An array of one char is just an array in which you can store a single char value.

If you can't change the definition from an array to a pointer then you can't make it "point". I'm afraid it's as simple as that.


This is a very common paradigm in C. The last char is just a placeholder for variable data, and in reality you will allocate a larger buffer and overrun the 1 character. This is perfectly legal.

You cannot change the struct but when you call malloc() to allocate it you allocate some extra bytes.

What you need in place of the char[1] is a pointer (to the other struct).

Let us give your struct a name:

typedef struct{
    Variable a;
    Variable 2;
    char ch[1];
} Element;

in your code:

Element * elt = malloc( sizeof( Element ) + sizeof( CharArrayStruct* ) - 1);
 /* fill your struct */
*(CharArrayStruct **)elt.ch = &myCharArrayStruct;
/* later on reading it back */
CharArrayStruct * pcas = *(CharArrayStruct **)elt.ch;

Note elt.ch is the address of the start of an array, not a char. Note that its contents are an OtherStruct* therefore it must be cast to CharArrayStruct**


You could come up with a third struct:

struct c {
    struct a *a;
    struct b *b;
    struct c *next;
}

Append a new one of these to a head each time you want to store an association from your struct a to your struct b -- when you need to look one up, walk down the linked list, doing pointer comparisons on .a until you find the matching one, and return the .b.

Don't forget to remove these entries from the linked list when you free() struct a objects, and don't forget to NULL the .b members when you free() struct b objects.


I don't think it's possible to do in a safe way, at least not unless you're in some low-memory environment. A single char (which is what your ch field is) only consists of 1 byte; this is simply not enough bits to point to any memory location in your virtual memory space. Even if you cast that char to (void *) you won't be able to address the vast, vast majority of your memory with it.

Perhaps you should step back and tell us what you're actually trying to accomplish, rather than what you think you need to do in order to accomplish it.


If you mean what you literally say in the actual question body ("I just need some how to put the first byte of my second struct in ch[1] and I simply don't know how to do this."), and I disregard the first sentence that talks about "pointing", you could do it like this:

struct{
    Variable a;
    Variable 2;
    char ch[1];
} my_struct_that_cant_be_changed;

struct my_other_struct x;

my_struct_that_cant_be_changed.ch[0] = *(char *) &x;

This simply reads the first char from the other struct (in the variable x) and assigns that value into the 1-character array of the first struct.

Note that this seems completely pointless to me, but it does (sort of) what you want.


First, it's not clear what you want to do. It's not possible to "point" to another struct using a one-byte value. Secondly, it doesn't make sense to place the first byte of the second struct in ch[0] without doing anything else.

The way the struct is constructed I suspect that that it is designed to be a variable length struct. (Other answers have touched this, but they use the extra space to store a pointer, not the entire string.)

By allocating some extra bytes, you would get the following layout in memory:

+----
| Variable a
| Variable 2 (sic)
| ch[0]
+------ Extra memory below:
| ch[1]
| ...
| ch[N]
+------

You can allocate this by:

p = malloc(sizeof(Element) + N);

You can access the element like p->ch[4] and access ch as a string using p->ch.

Now, it's up to you to fill your ch array with the string (or whatever) you want.

0

精彩评论

暂无评论...
验证码 换一张
取 消