C - transferring information to a struct (specifically an array of strings) - c

This seems to be a very simple problem but I can't quite figure out which part is causing it. Basically, I have a struct that just contains an array of strings
struct command_stream{
char **tokens;
};
typedef struct command_stream *command_stream_t;
command_stream_t test;
Then later on, I parse some strings into shorter ones and end up with another array of strings
char **words = *array of strings*
words contains the correct information I want, I looped through and printed out each element to make sure I wasn't getting a faulty string. So now I just point tokens to words
test->tokens = words;
But it gives me a segmentation fault. I'm not sure why though. They're both pointers, so unless I'm missing something obvious...
EDIT: The function as a whole has to return a pointer, which is why it was set up like this, which I keep forgetting. But I think I've got it, if I just create a new typedef
typedef struct command_stream command_stream_s;
command_stream_s new_command_stream;
and just return
&new_command_stream;
That should work right? Even though new_command_stream itself isn't a pointer.

From your code excerpt, it seems that you have not declared the struct. You have successfully declared a pointer to the struct command_stream_t test; but this pointer does not point to anywhere yet.
You need to allocate memory for your struct in some way and make test reference it. For instance:
command_stream_t test =
(command_stream_t) malloc(sizeof(struct command_stream));
This way you can successfully use:
test->tokens = words;
as you intended.
Note that you don't need to use malloc to allocate the memory. The pointer can reference a local/global variable as long as it has memory associated to it (N.B. if you use a local var don't use the pointer outside the declaration scope of that var).

typedef struct command_stream *command_stream_t;
command_stream_t test;
This makes "test" a pointer. There is no memory allocated for the structure.
You need to allocate memory for the structure and make the test pointer point to the block of memory before you can dereference by saying -
test->tokens = words;
Do this:
typedef struct command_stream command_stream_t;
command_stream_t test;
test.tokens = words;
The difference is that, command_stream_t is no more a pointer type, it is the actual structure.

Related

Memory allocation of nested char pointer

I have a question regarding the allocation of memory for a given char pointer inside a struct. The following typedef bson_value_t is given by an API and I would like to use it inside my own typedef ObjectInfo, shown in my code:
typedef struct _bson_value_t {
bson_type_t value_type;
union {
int64_t v_int64;
int32_t v_int32;
int8_t v_int8;
double v_double;
struct {
uint32_t len;
char *str;
} v_utf8;
} value;
} bson_value_t;
typedef struct _ObjectInfo {
char key[100];
bson_value_t value;
} ObjectInfo;
I have other data packages that contain hundreds of these ObjectInfo types, but all simply initalized like:
typedef _DataPackage {
ObjectInfo single;
ObjectInfo multiple[100];
...
} Datapackage;
So they do not contain any usefull data yet. I would like to use strcpy to put a string to the location where char *str is pointing. But as far as I know that does not work because there is no allocated memory where *str is pointing to, right?
My question would be, how do I accomplish that without changing the given typedef bson_value_t? Do I need to allocate memory for any one bson_value_t that I initialized?
strcpy(DataPackage.single.value.value.v_utf8.str, "test");
That does not work, unless I change it to:
strcpy(&DataPackage.single.value.value.v_utf8.str, "test");
but this is giving me compiler warnings.
I would like to use strcpy to put a string to the location where char *str is pointing. But as far as I know that does not work because there is no allocated memory where *str is pointing to, right?
Right.
My question would be, how do I accomplish that without changing the given typedef bson_value_t? Do I need to allocate memory for any one bson_value_t that I initialized?
No, you do not (for this purpose) need to dynamically allocate memory for any bson_value_t. The space, if any, to which any of those value.v_utf8.str members point will be external to the the bson_value_t, so arranging for that memory is a separate consideration.
As far as the data structure itself is concerned, the string data could be dynamically allocated, or they could be statically allocated (such as the contents of a string literal), or they could even be a locally-declared array (automatically allocated), though this last will present issues if the lifetime of the string data is shorter than that of the bson_value_t.
However, do make sure that you know what assumptions are made by the library from which you are drawing this. For example, if any of its functions assume that they can reallocate space to provide for lengthening the string, or if they assume that they can modify the contents in place, then such assumptions affect what kind of storage you need to provide.

Trouble with structs and strings

I made a linked list whose nodes hold 4 string values. When I call the newNode function, an error says 'Node has no member named familyName', as well as the other members. My code:
I am really confused with how strings work in structs.
Your immediate problem is the type definition. You cannot call malloc() from within there, all you can do is define the fields. The memory allocation must come later. So, it should be:
typedef struct node{
char *familyName;
char *firstName;
char *address;
char *phoneNumber;
struct node *link;
}Node;
You'll strike another problem (run-time rather than compile-time) once you fix that. When you do something like:
p -> familyName = famName;
that simply copies the pointer into your structure, and the pointer is always the memory location of familyName in main().
That means every node will point to the same memory, and you're continuously updating that memory.
You won't notice the problem with the code as it stands, since you're only asking for one record. But it will become an issue when you start looping to get more records.
Your best bet is to use something like strdup() to make a copy of the string passed in, then each node will have its own memory location for strings:
p -> familyName = strdup (famName);
(don't forget to also free() the memory for each field once you're finished with it).
In the unlikely event your C implementation doesn't have a strdup(), see here.
There are several problems:-
It is not allowed to allocate memory when declaring a structure. Either, do the malloc inside your newNode() method Or, declare the structure like char familyName[50].
Result of malloc should not be casted.
It is better to use strcpy (or strdup) when copying strings

C - passing elements from within structures to functions

I have a structure comprised of an array of pointers to other structures of a different type.
typedef struct{
NodeT* nodes[2];
int size;
}stackT;
with:
typedef struct{
char info;
}NodeT;
And I have a pointer to the above (first) structure:
stackT* stackPtr;
Assuming the memory is allocated for the stackT structure as well as both NodeT structures with associated assignments for the members of both NodeT structures, how would I pass to a function one of the pointers in stackT?
For example:
void setChar(NodeT* nodePtr, char setTo){
nodePtr->info = setTo;
}
called with line:
setChar(stackPtr->nodes[0], 'A');
Does not work. I figured it had something to do with the -> syntax dereferencing the pointer whereby I am actually passing in a structure. I do not get any compilation errors, but when I check for the assignment by printing whatever is stored in char info I do not get anything.
Is the notation incorrect or do I have issues elsewhere in the program perhaps? I just wanted to rule this out first (proper passing syntax).
If someone is looking for a solution to this problem, the above code was actually correct.
Assuming you have an array of pointer in some structure and you wish to pass such a pointer, the correct syntax would be:
someFunc( structPtr->ptrArray[0] )
The line:
structPtr->ptrArray[0]
Actually returns a pointer, and not whatever the pointer is pointer to.
(*structPtr).ptrArray[0]
Is also equivalent.
That being said, I either mistakenly interpreted the information before me, or I had underlying errors elsewhere in the my code.

malloc in c, struct

I made a struct like this:
struct a{
char *name;
char *value;
struct a *next;
};
when I malloc for memory at first time, it's ok, and I can set 'name' and 'value' a corresponding value.
but when I malloc for the second time, errors come. And It's a cgi, just show me "500 Internal server error".
I changed the pointer 'name' and 'value' to array, everything works.
I thought maybe the complier doesn't know how much memory to assign.
And do you have some ideas with this? I will appreciate every answer!
struct a {
char *name;
char *value;
struct a *next;
};
struct a *head = malloc(sizeof *head);
The above allocates space for a single struct a object, but it doesn't initialize any of hte three pointers contained in a struct a. In particular, if you want name and value to point to strings, you'll need to allocate space for those strings:
head->name = malloc(5);
strcpy(head->name, "Fred");
head->value = malloc(8);
strcpy(head->value, "abcdefg";
This is considerably oversimplified. 5 and 8 are "magic numbers"; you should specify the sizes in a way that will remain consistent if you change the initial values. And you should always check whether malloc() returns a null pointer (even if you just terminate the program with an error message).
If you don't initialize name and value to point to some chunk of allocated memory, you might still be able to initialize what they point to (e.g., by doing the strcpys above without the mallocs). More precisely, the system won't necessarily diagnose the error.
Finally, you'll need a call to free() corresponding to each malloc() call.
Note that this is largely a guess based on your description. If you can show us your actual code, we can help you better.
If you use malloc with sizeof(struct a) it's just going to assign enough space to store the pointers name and value. You want these to be char arrays, then it'll know how much space to set aside for each instance of a.

Defining an array of structures in C?

main.h
#define DATA struct data
DATA
{
int id;
char data;
}
main.c
DATA *listOfData[100];
So at this point I will/should be able to access DATA in the list like this:
printf(listOfData[5]->data);
It isn't letting me do it, the run just freezes on that last print f...no error or anything.
This is because you have defined an array of pointers. But you never initialized any of the pointers.
Therefore:
printf(listOfData[5]->data);
will crash (undefined behavior) because you are dereferencing the (invalid) pointer at index 5.
*(And that's a very odd way to define a struct...)
To fix this issue, you will need to allocate for each of the pointers in the array. If you don't actually need it to be an array of pointers, then it might be better to just make it array of the struct itself:
DATA listOfData[100];
and access it as:
listOfData[5].data
Then you don't have to deal with allocating each element.
I'm not sure why printf would just freeze, but there's a couple of things wrong with this. First, all the pointers in your DATA* array are uninitialized. You probably intended to make an array of DATA, instead of an array of DATA pointers:
DATA listOfData[100];
You also didn't end the struct with a semicolon, so it seems unlikely that this would even compile:
#define DATA struct data
DATA
{
int id;
char data;
};
Finally, you're using printf in a rather unsafe way; the first argument needs to be a format string, or you can get weird behavior if the first argument has a % in it:
printf("%c\n", listOfData[5].data);
You haven't shown any memory allocation for the DATA *. Either declare your array as an array of struct data, like:
DATA listOfData[100];
or allocate memory dynamically and assign the pointers in your array.

Resources