0

With your help here in this site (the question is here), I've created a struct pointer as following:

struct myStruct {
   char charVar;
   int intVar;
};
int indexnum = 1;
struct myStruct *p = NULL;
p = malloc(sizeof *p);
p[indexnum].member = x;
index++;

everytime I add a new struct, I increase 'indexnum' so I give different names for each struct.

"mystruct" is global, but the declaration "struct myStruct *p" is in the main function.

the problem is, I cannot reach that p structs from other functions. I just couldn't figure out how to.

The following code is just one of the many trials,

void func1 (char str1, int index, int num1){
int i=0;
struct myStruct *p = NULL; 
p[i].charVar="adadsasd";

When the debugger reaches this last line, I get this error: Unhandled exception at ...... Access violation writing location

What should I do?

Community
  • 1
  • 1
user3108849
  • 111
  • 3
  • 12

3 Answers3

3

It looks like you are trying to create an array of struct myStructs. There are a few ways to do so. The first is to allocate the structs on your stack ala:

struct myStruct p[N];

where N is some positive integer value. Note that by declaring this array on the stack, once your program leaves the scope of wherever this array was declared in, the array and all its contents become lost. Example:

struct myStruct foo(int N) {
    int i;
    struct myStruct p[N];
    for(i = 0; i < N; i++)
        p[i].intVar = i;

    for(i = 0; i < N; i++)
        //Prints value of intVar of each struct myStruct on a different line
        printf("%d\n", p[i].intVar); 

    // Returns p but the moment the scope returns to the main function, p
    // ceases to exist
    return p;
}

int main() {
    struct myStruct p[10] = foo(10);

    // This gives you an error as the program has no notion of p outside the scope
    // of foo
    printf("%d\n", p[5].intVar);
}

The other option is to allocate the array onto the heap ala:

struct myStruct **p = malloc(N * sizeof(struct myStruct *));

Note that constructing an array like this means you have to also allocate space on the heap for each struct in the array. Example:

struct myStruct** foo(int N) {
                      struct myStruct **p = malloc(N * sizeof(struct myStruct *));
                      int i;
                      for(i = 0; i < N; i++)
                          p[i] = malloc(sizeof(struct myStruct));

                      return p;
                   }

int                main() {
                       struct myStruct **p = foo(10);
                       p[5]->intVar = 10;

                       // This is now valid because p and its elements
                       // exist on the heap until you free them
                       printf("%d\n", p[5]->intVar);

                       // For every malloc you must have a free, lest
                       // you run into memory leaks
                       int i;
                       for(i = 0; i < 10; i++)
                           free(p[i]);
                       free(p);

                   }
michael60612
  • 397
  • 2
  • 10
  • 5
    `sizeof *p` will be the same as `sizeof(struct myStruct)` because the type of `*p` **is** `struct myStruct`. The type of `p` is a pointer type, and therefore `sizeof p` will be the size of a pointer type. – dreamlax Dec 27 '13 at 22:23
  • 2
    Also, it has been said countless times before, [you shouldn't cast the result of `malloc`](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – dreamlax Dec 27 '13 at 22:24
  • @Dreamlax is right please disregard my answer. It seems to me you might be trying to allocate an array of `struct myStruct`s? – michael60612 Dec 27 '13 at 22:29
  • Try this: `struct myStruct p[10];`. It seems like you're trying to create an array of structs and that is how you do it. You can replace 10 with whatever number you need. If you're trying to create them on the heap, try `struct myStruct **p = malloc(10 * sizeof(struct myStruct));`. Also note that if you do allocate them on the heap, to access a member of the struct you must do `p[i]->member` – michael60612 Dec 27 '13 at 22:41
  • p[i].member thing Works in the main function. Also, I don't actually know how many elements I will create so I want it to be created dynamically each time instead of limiting it 10 or anything else. @michael60612 – user3108849 Dec 27 '13 at 22:57
  • You forgot the 3rd option: It is similiar to the 1st one, but allocates the whole array on the heap: `struct myStruct * p = malloc(N * sizeof(struct myStruct));`. Then you have enough space to store `N` consecutive `myStruct`s and can access them via `p[0]`, `p[1]` and so on up to `p[N-1]`. – glglgl Dec 28 '13 at 08:00
  • @michael60612: The last line should be `free(p);`. Also why not just simply allocate the p array like `struct myStruct * p = malloc(N * sizeof(struct myStruct));` (see @glglgl comments) and then return `struct myStruct* foo(int N)` in the function `foo`? It seems to be simpler. – tonga Dec 28 '13 at 16:10
  • @tonga Thanks for the catch! Also you're right, that is a valid and probably sufficient solution for most cases. I had been working with allocating multidimensional arrays earlier and was still in that mode of thinking! Cheers :) – michael60612 Dec 28 '13 at 17:10
1

You need to redefine your struct as

struct myStruct {
   char* charVar;
   int intVar;
};

So that charVar is a pointer to a string. Then when you want to set the string value, you can use strcpy. Also you need to malloc for each charVar with NUM_CHARS being the maximum length of each string.

for(i=0; i < num_of_elements; i++) {
    p[i].charVar = (char*) malloc(sizeof(char)*NUM_CHARS);    
    strcpy(p[i].charVar, "adadsasd");
}

Also note that when you allocate for p, you need to do the following:

struct myStruct *p;
p = (struct myStruct*) malloc(sizeof(struct myStruct)*num_of_elements);

so that p is a pointer to a struct array of type myStruct.

tonga
  • 11,749
  • 25
  • 75
  • 96
  • num of elements mean the number of existing p structs, right? – user3108849 Dec 27 '13 at 22:53
  • `num_of_elements` is how many elements you want to create for the struct array. You can define it somewhere in your code before calling `malloc` function. – tonga Dec 27 '13 at 22:54
  • If you declare `p` in your `main` function, it cannot be accessed from other functions. So you need to either put the declaration of `p` in the function you are going to use `p`, or you can make `p` a global variable. – tonga Dec 27 '13 at 22:57
  • You need a malloc for each charVar too – deviantfan Dec 27 '13 at 22:59
  • I put the 'struct myStruct *p = NULL;' declaretion to func1, too. as you see in the question. problem must be something else – user3108849 Dec 27 '13 at 23:01
  • @deviantfan: Yes, thanks for reminding. I've updated my answer. – tonga Dec 27 '13 at 23:03
  • still not helpful for other funcs. :( – user3108849 Dec 27 '13 at 23:08
  • You shouldn't cast the result of [`malloc`](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – dreamlax Dec 27 '13 at 23:49
  • I just can't see how will malloc help me with accessing p. you are just focusing on somewhere else man. – user3108849 Dec 28 '13 at 14:09
  • You want to access `p` outside your function. That's why you need to malloc p so that it can be accessed from outside. – tonga Dec 28 '13 at 15:12
  • @dreamlax: Thanks for your comments. I've been using this casting style for so long and not using casting is a good practice. – tonga Dec 28 '13 at 16:16
  • I already malloc p. you mean I should malloc p outside of the main function? – user3108849 Dec 28 '13 at 16:30
  • Let me tell you exactly what I am trying to do here. I declare "mystruct" globally. I will do processes of p structs in the main function and other functions. I create a new p struct in func1, and change some of it contents in some other functions. All the functions are directed from main function. Whatever I try, I always get the same error. – user3108849 Dec 28 '13 at 16:33
  • Note sure about the details about your code since you haven't fully posted it in your post. But if you want that way, then you can use michael60612's comments above. Basically return a pointer to a dynamically allocated array from func1(), and then use it in other functions and main. Then you need to finally free the memory after all usage. – tonga Dec 28 '13 at 16:45
  • OK thanks for all your interest. I will try to start over from the beginning and re-write all the code to find the real root of the error. Then I will come back here if I still can't solve it. Thanks again :) – user3108849 Dec 28 '13 at 20:01
0

If you want to change the value of 'p' pointer from another function this can be done by passing pointer to pointer as function parameter

The code sample is as follows:

void test(int **q){
          *q = malloc(sizeof(int));
          **q = 1;
   }        

   int main(){
            int *p;
          test(&p);
          printf("%d", *p);
          free(p);
          return 0;
  }     
  • The thing is, that the program finds the specific p struct in the func1 function (like your test function), so I cannot send a specific p to it – user3108849 Dec 27 '13 at 23:10
  • I am seeing in your func1 you are creating new 'p' pointer. You can't access the local 'p' pointer of 'func1' from 'main' function `void func1 (char str1, int index, int num1){ int i=0; struct myStruct *p = NULL;` – Habibullah Araphat Konok Dec 27 '13 at 23:24
  • I think you want to access both the local and global variable in func1. If you are trying to do this I will suggest you to change the name of local 'p' pointer. – Habibullah Araphat Konok Dec 27 '13 at 23:34
  • okay I renamed it as q but I still don't know how to reach it – user3108849 Dec 28 '13 at 14:08