Adding an array element to an array in a struct - c

(Proficient at C++, newbie at C) getting a segfault error from the addArray() call in main(). I've checked many posts and several texts, it compiles, but no luck running it. I'm coding it on VS2015 and all the usual handy cues are there with pointers, etc. Cleary something I'm not aware of or a syntax error. This is the distilled code that reproduces the error.
#include<stdio.h>
#include <stdlib.h>
#define TYPE int
struct arrayHolder {
TYPE data[100];
int count;
};
//prototypes.
void initArray(struct arrayHolder * );
void addArray(struct arrayHolder *, TYPE);
int main() {
struct arrayHolder * myStruct = NULL;
initArray(myStruct);
addArray(myStruct, 123);
}
/* Allocate memory for struct arrayHolder */
void initArray(struct arrayHolder * b) {
b = (struct arrayHolder *)malloc(sizeof(struct arrayHolder));
b->count = 0;
}
/* Add an element to data[] */
void addArray(struct arrayHolder * b, TYPE v) {
int count = b->count;
b->data[count] = v;
(b->count)++;
}

As #def1 observed, you are passing pointers by value. That's not an issue for addArray() -- the problem is with initArray(). That function's parameter is local to the function, so when you assign the malloc()ed pointer to it, the result is not visible in main(). Ultimately, you end up passing a NULL pointer to addArray().
There are at least two possible solutions.
In the code presented, it's not clear to me why the struct arrayholder needs to be dynamically allocated at all. If in main() you declare instead struct arrayholder myStruct; and remove the malloc() call from initArray(), then everything else should work as-is.
Alternatively, if you do need to perform dynamic allocation then either you should return a pointer to the allocated memory from initArray() (in which case that function does not require a parameter) or else you need to pass a double pointer to the function, so that main()'s pointer can be updated thereby.
The only one of those alternatives that should be at all tricky is the double pointer variant, which would look like this:
int main() {
struct arrayHolder * myStruct = NULL;
initArray(&myStruct); /* difference here */
addArray(myStruct, 123);
}
/* Allocate memory for struct arrayHolder */
void initArray(struct arrayHolder ** b) {
/* no cast is required here in C, and many account one poor style: */:
*b = malloc(sizeof(struct arrayHolder));
(*b)->count = 0;
}

void initArray(struct arrayHolder * b)
Here you pass a pointer to a struct arrayHolder to the function. The pointer is passed by value which means it is a copy. You can change the data the pointer is pointing to but when you assign the result of malloc to b you are modifying the copy of the pointer itself, which will not influence the pointer in main.
Possible solution is to use a pointer to a pointer.
void initArray(struct arrayHolder ** b) {
*b = (struct arrayHolder *)malloc(sizeof(struct arrayHolder));
(*b)->count = 0;
}

Related

Struct with pointer to function

can you please explain in details this line of code inside struct:
There is a pointer to function but why would you reference it to struct?
void (*function)(struct Structure *);
what does this mean
(struct Structure *)?
(struct Structure *)
It means that the function have a struct Structure * argument. Actually it will make more sense with (struct Structure *variable of struct).
In this way, you can use a pointer to point a struct and should put the address of the struct variable which can be used in the function.
#include <stdio.h>
typedef struct circle{
int rad;
int area;
} Circle;
void ShowCircleInfo(Circle *info)
{
printf("rad value: %d\n", info->rad);
printf("area value: %d", info->area);
}
int main(void)
{
Circle circle_one;
circle_one.rad = 2;
circle_one.area = 3;
ShowCircleInfo(&circle_one);
return 0;
}
void (*function)(struct Structure *); declares function to be a pointer to a function that has a parameter of type struct Structure * and does not return a value.
For example
#include <stdio.h>
struct Structure {
int a;
void (*function)(struct Structure *);
};
void foo(struct Structure *a) {
if (a->function == NULL) a->function = foo;
a->a++;
printf("%d\n", a->a);
}
int main(void) {
struct Structure a = {42, foo};
struct Structure b = {0}; // don't call b.function just yet!!
a.function(&b); // foo(&b)
b.function(&a); // foo(&a)
}
See code running at https://ideone.com/7E74gb
In C, function pointer declarations have almost the same structure as function headers.
Only the function name will change to have some parantheses and a "*" in it, and the arguments won't have names, because only their types are important when using pointers (we don't access the values of the arguments, so we don't need their names).
They basically look like this:
<return_value> (*<function_name>)(<argument_list>)
So, for example, the function pointer for the function
void swap(int* a, int* b);
would be
void (*swap_ptr)(int*, int*);
Notice that the name of the pointer is in the place of the name of the function, and looks a bit odd compared to normal pointer declarations.
An excellent reading on this topic (you can skip the C++ stuff): https://www.cprogramming.com/tutorial/function-pointers.html

Can I iterate dynamic array without knowing the size of it

I allocated some data in a dynamic array of a struct. Can I iterate that struct * without knowing it's size somehow?
Would this work?
int main() {
struct *foo = NULL;
//struct filling
iterate_foo(foo);
}
void iterate_foo(struct *foo) {
int i=0;
while (foo[i] != NULL) { // Would this work?
//something
}
}
The only way that can work is if you have a sentinel value in the array that indicates the end. Strings in C work that way.
For instance, if you invoke strcpy(a, b), then characters from b will be copied to a until and including the value zero. If there's no zero terminator within the b array, or if a is not big enough to hold all the characters, the function call leads to undefined behavior.
If you don't want to use a sentinel value, you have the option of passing the size as a separate parameter. Another way is to wrap things in a container struct, like this:
struct container {
struct mystruct *data;
size_t size;
}
Furthermore, struct *foo = NULL; is wrong. It has to be something like struct mystruct *foo = NULL;
But if you have this code:
void foo(T *ptr) {
// Do something
}
int main(void) {
T *a = malloc(N * sizeof *a);
T b[N];
foo(a);
foo(b);
}
Then it's completely impossible for foo to figure out N in a portable way. In some cases, believe that the implementation of malloc stores the size right before the data. But don't try to exploit that. It will only cause severe head ache.

Segmentation Fault while trying to fill a list [duplicate]

Suppose I have the following struct and function returning a pointer:
typedef struct {
int num;
void *nums;
int size;
} Mystruct;
Mystruct *mystruct(int num, int size)
{
//Is the following correct? Is there a more efficient way?
Mystruct mystruct;
mystruct.num = num;
mystruct.size = size;
mystruct.nums = malloc(num*sizeof(size));
Mystruct *my;
*my = mystruct;
return my;
}
I want to define any Mystruct pointer using the above function. Should I declare a Mystruct variable, define the properties of Mystruct, assign a pointer to it, and return the pointer or define the properties of a mystruct property through a pointer immediately?
Should I declare a Mystruct variable,
define the properties of Mystruct,
assign a pointer to it, and return the
pointer
Definitely not, because the variable defined in the function (in "auto" storage class) will disappear as the function exits, and you'll return a dangling pointer.
You could accept a pointer to a Mystruct (caller's responsibility to allocate that) and fill it in; or, you can use malloc to create a new one (caller's responsibility to free it when it's done). The second option at least lets you keep the function signature you seem to be keen on:
Mystruct *mystruct(int num, int size)
{
Mystruct *p = malloc(sizeof(MyStruct));
....
return p;
}
but it's often an inferior one -- since the caller has to have responsibilities anyway, may as well go with the first option and potentially gain performance (if the caller can use an auto-class instance because it knows the scope of use is bounded).
You can't use the variable because it will be deallocated when the function exits. For example:
Mystruct *mystruct(int num, int size)
{
MyStruct x;
x.num = 1;
...
return &x;
}
Will give a segmentation fault or access violation because the memory for x is deallocated as soon as you exit. So you have to allocate memory for the struct (and be sure to free it up later) or declare a global that will stay around for ever. Example for the latter...
Mystruct *mystruct(int num, int size)
{
MyStruct *x;
x = (MyStruct*)malloc( sizeof( MyStruct ) );
x->num = 1;
...
return x;
}
If you are writing generic code and you don't know how it may be used, it's good to provide both options:
int mystructm(Mystruct *storage, int num, int size)
{
int rv = 0;
storage->num = num;
storage->size = size;
storage->nums = malloc(num*sizeof(size));
if (!storage->nums)
return -1;
return 0;
}
Mystruct *mystruct(int num, int size)
{
Mystruct *mp = (Mystruct *)malloc(sizeof(Mystruct));
if (mp)
{
if (mystructm(mp, num, size) == -1)
{
free(mp);
mp = NULL;
}
}
return mp;
}
The idea is that as a library writer, you shouldn't dictate policy (such as that each Mystruct must be dynamically allocated) but should let the application writer decide that.
It's important to remember that the pointer is not something you assign to the structure, but rather the pointer indicates the location in memory that you wish to treat as a structure. Based on your question, you really want to allocate the memory to hold the data structure. This gives you a pointer to the memory location allocated. Once you have that, you can return it.
EDIT (after edit to original question)
Looking at your edit to the question, you definitely will have problems with the "my" pointer. This is uninitialised, and may point to anywhere in memory. When you attempt to copy the structure to it, you'll probably get a seg-fault.
Allocating a new Mystruct and returning a pointer to it would usually look more or less like this:
Mystruct *mystruct(int num, int size)
{
Mystruct *result;
result = malloc(sizeof(MyStruct));
if (!result)
return NULL;
result->num = num;
...
return result;
}
Later, when you are done with the Mystruct allocated here with malloc, it should be freed again with free().
Just declaring a local variable and returning a pointer to that local variable will not work. The local variable goes out of scope at the end of the function and the memory where it was stored is most likely reused for other purposes. The returned pointer will still point to the memory location where the local variable once was, but since that variable doesn't exist anymore, that pointer wouldn't be of much use.
One more way to do it..
int mystruct(Mystruct *mystruct, int num, int size){
if(mystruct == NULL)
return -1;
mystruct->num = num;
mystruct->size = size;
::
return 0;
}
int main(){
Mystruct my;
if(mystruct(&my, 3, 4) != 0){
fprintf(stderr, "Cannot init!\n");
exit(0);
}
::
}

Passing a pointer to dynamic array

Is it a right way to pass a pointer to dynamic array? Is it going to work? If not, explain why, if it does, explain why as well. Thank you.
struct record
{
char * community_name;
double data[10];
double crimes_per_pop;
};
void allocate_struct_array(struct record *** r);
int main()
{
/* allocating pointer to an array of pointers */
struct record ** r;
/* passing its address to a function */
allocate_struct_array( &(**r) );
}
/* function gets an address */
void allocate_struct_array(struct record *** r)
{
...
}
What I was trying to do is to allocate an array of pointers, where each pointer points to structure record. Function suppose to allocate this array using just pointer to r, which was declared in main. Was playing with this code, but cannot make it to work.
I don't know what you are trying to do, but at least you have a programmatic error.
allocate_struct_array( &(**r) );
needs to be -
allocate_struct_array(&r);
In the function interface, you only need a double pointer struct record **r and not a triple pointer.
An array can be represented by a struct record *array; so a pointer to that is struct record **ptr_to_array.
You call the function with &array.
struct record
{
char * community_name;
double data[10];
double crimes_per_pop;
};
void allocate_struct_array(struct record **r);
int main()
{
struct record *r;
allocate_struct_array(&r);
}
void allocate_struct_array(struct record **r)
{
*r = malloc(23 * sizeof(struct record));
...
}

Returning a struct pointer

Suppose I have the following struct and function returning a pointer:
typedef struct {
int num;
void *nums;
int size;
} Mystruct;
Mystruct *mystruct(int num, int size)
{
//Is the following correct? Is there a more efficient way?
Mystruct mystruct;
mystruct.num = num;
mystruct.size = size;
mystruct.nums = malloc(num*sizeof(size));
Mystruct *my;
*my = mystruct;
return my;
}
I want to define any Mystruct pointer using the above function. Should I declare a Mystruct variable, define the properties of Mystruct, assign a pointer to it, and return the pointer or define the properties of a mystruct property through a pointer immediately?
Should I declare a Mystruct variable,
define the properties of Mystruct,
assign a pointer to it, and return the
pointer
Definitely not, because the variable defined in the function (in "auto" storage class) will disappear as the function exits, and you'll return a dangling pointer.
You could accept a pointer to a Mystruct (caller's responsibility to allocate that) and fill it in; or, you can use malloc to create a new one (caller's responsibility to free it when it's done). The second option at least lets you keep the function signature you seem to be keen on:
Mystruct *mystruct(int num, int size)
{
Mystruct *p = malloc(sizeof(MyStruct));
....
return p;
}
but it's often an inferior one -- since the caller has to have responsibilities anyway, may as well go with the first option and potentially gain performance (if the caller can use an auto-class instance because it knows the scope of use is bounded).
You can't use the variable because it will be deallocated when the function exits. For example:
Mystruct *mystruct(int num, int size)
{
MyStruct x;
x.num = 1;
...
return &x;
}
Will give a segmentation fault or access violation because the memory for x is deallocated as soon as you exit. So you have to allocate memory for the struct (and be sure to free it up later) or declare a global that will stay around for ever. Example for the latter...
Mystruct *mystruct(int num, int size)
{
MyStruct *x;
x = (MyStruct*)malloc( sizeof( MyStruct ) );
x->num = 1;
...
return x;
}
If you are writing generic code and you don't know how it may be used, it's good to provide both options:
int mystructm(Mystruct *storage, int num, int size)
{
int rv = 0;
storage->num = num;
storage->size = size;
storage->nums = malloc(num*sizeof(size));
if (!storage->nums)
return -1;
return 0;
}
Mystruct *mystruct(int num, int size)
{
Mystruct *mp = (Mystruct *)malloc(sizeof(Mystruct));
if (mp)
{
if (mystructm(mp, num, size) == -1)
{
free(mp);
mp = NULL;
}
}
return mp;
}
The idea is that as a library writer, you shouldn't dictate policy (such as that each Mystruct must be dynamically allocated) but should let the application writer decide that.
It's important to remember that the pointer is not something you assign to the structure, but rather the pointer indicates the location in memory that you wish to treat as a structure. Based on your question, you really want to allocate the memory to hold the data structure. This gives you a pointer to the memory location allocated. Once you have that, you can return it.
EDIT (after edit to original question)
Looking at your edit to the question, you definitely will have problems with the "my" pointer. This is uninitialised, and may point to anywhere in memory. When you attempt to copy the structure to it, you'll probably get a seg-fault.
Allocating a new Mystruct and returning a pointer to it would usually look more or less like this:
Mystruct *mystruct(int num, int size)
{
Mystruct *result;
result = malloc(sizeof(MyStruct));
if (!result)
return NULL;
result->num = num;
...
return result;
}
Later, when you are done with the Mystruct allocated here with malloc, it should be freed again with free().
Just declaring a local variable and returning a pointer to that local variable will not work. The local variable goes out of scope at the end of the function and the memory where it was stored is most likely reused for other purposes. The returned pointer will still point to the memory location where the local variable once was, but since that variable doesn't exist anymore, that pointer wouldn't be of much use.
One more way to do it..
int mystruct(Mystruct *mystruct, int num, int size){
if(mystruct == NULL)
return -1;
mystruct->num = num;
mystruct->size = size;
::
return 0;
}
int main(){
Mystruct my;
if(mystruct(&my, 3, 4) != 0){
fprintf(stderr, "Cannot init!\n");
exit(0);
}
::
}

Resources