开发者

Assigning memory to double pointer?

I am having trouble understanding how to assign memory to a double pointer. I want to read an array of strings and store it.

    char **ptr;
    fp = fopen("file.txt","r");
    ptr = (开发者_开发百科char**)malloc(sizeof(char*)*50);
    for(int i=0; i<20; i++)
    {
       ptr[i] = (char*)malloc(sizeof(char)*50);
       fgets(ptr[i],50,fp);
    }

instead of this I just assign a large block of memory and store the string

  char **ptr;
  ptr = (char**)malloc(sizeof(char)*50*50);

would that be wrong? And if so why is it?


Your second example is wrong because each memory location conceptually would not hold a char* but rather a char. If you slightly change your thinking, it can help with this:

char *x;  // Memory locations pointed to by x contain 'char'
char **y; // Memory locations pointed to by y contain 'char*'

x = (char*)malloc(sizeof(char) * 100);   // 100 'char'
y = (char**)malloc(sizeof(char*) * 100); // 100 'char*'

// below is incorrect:
y = (char**)malloc(sizeof(char) * 50 * 50);
// 2500 'char' not 50 'char*' pointing to 50 'char'

Because of that, your first loop would be how you do in C an array of character arrays/pointers. Using a fixed block of memory for an array of character arrays is ok, but you would use a single char* rather than a char**, since you would not have any pointers in the memory, just chars.

char *x = calloc(50 * 50, sizeof(char));

for (ii = 0; ii < 50; ++ii) {
    // Note that each string is just an OFFSET into the memory block
    // You must be sensitive to this when using these 'strings'
    char *str = &x[ii * 50];
}


 char **ptr;
    fp = fopen("file.txt","r");
    ptr = (char**)malloc(sizeof(char*)*50);
    for(int i=0; i<50; i++)
    {
       ptr[i] = (char*)malloc(sizeof(char)*50);
       fgets(ptr[i],50,fp);
    }

fclose(fp);

may be your typo mistake but your loop should be of 50 instead of 20 if you are looking for 50 x 50 matrix. Also after allocation of memory mentioned above you can access the buffer as ptr[i][j] i.e in the 2D format.


A double pointer is just a pointer to another pointer. So you can allocate it like this:

char *realptr=(char*)malloc(1234);
char **ptr=&realptr;

You have to keep in mind where your pointer is stored at (in this example the double pointer points to a pointer variable on the stack so it's invalid after the function returns).


i will give one example, which might clear of the doubt,

char **str;                              // here its kind a equivalent to char *argv[]
str = (char **)malloc(sizeof(char *)*2)  // here 2 indicates 2 (char*)
str[0]=(char *)malloc(sizeof(char)*10)   // here 10 indicates 10 (char)
str[1]=(char *)malloc(sizeof(char)*10)   // <same as above>

strcpy(str[0],"abcdefghij");   // 10 length character 
strcpy(str[1],"xyzlmnopqr");   // 10 length character

cout<<str[0]<<endl;    // to print the string in case of c++
cout<<str[1]<<endl;    // to print the string in case of c++

or

printf("%s",str[0]);
printf("%s",str[1]);  

//finally most important thing, dont't forget to free the allocated mem
free(str[0]);
free(str[1]);
free(str);


other simpler way to memorize

Case -1 :

step-1 : char *p;

step -2 : please read it like below

char (*p); ==> p is a pointer to a char

now you just need to do malloc for the type (step-2) without braces

i.e., p = malloc(sizeof(char) * some_len);

Case -2 :

step-1 : char **p;

step -2 :

please read it like below

char* (* p); ==> p is a pointer to a char *

now you just need to do malloc for the type (step-2) without braces

i.e., p = malloc(sizeof(char *) * some_len);

Case -3 :

No one uses this but just for sake of explanation

char ***p;

read it as,

char** (*p); ==> p is a pointer to a char** (and for this check case-2 above)

p = malloc(sizeof(char**) * some_len);


Adding to Pent's answer, as he correctly pointed out, you will not be able to use this double pointer once the function returns, because it will point to a memory location on the function's activation record on stack which is now obsolete (once the function has returned). If you want to use this double pointer after the function has returned, you may do this:

char * realptr = (char *) malloc(1234);
char ** ptr = (char **) malloc(sizeof(char *));
*ptr = realptr;
return ptr;

The return type of the function must obviously be char ** for this.


well, this is how I do it:

#include <stdlib.h>

int main(void)
{
    int i = -1; // just a counter
    int j = 5; // how many strings
    char *s[j];
    while(++i < j)
        s[i] = malloc(sizeof(char*)); // allocating avery string separately
    return (0);
}

this also works:

char **allocate(int lines)
{
    int i = -1;
    char **s = malloc(sizeof(char *) * lines); // allocating lines
    while (++i < lines)
    {
        s[i] = malloc(sizeof(char*)); // alicating line
        scanf("%s", s[i]);
    }
    return (s);
}

int main(int ac, char *av[])
{
    int lines = 5; // how many lines
    char **s = allocate(lines);
    return (0);
}


Double pointer is, simply put, a pointer to a pointer, In many cases it is used as an array of other types.

For example, if you want to create an array of strings you can simply do:

char** stringArray = calloc(10, 40);

this will create an array of size 10, each element will be a string of length 40.

thus you can access this by stringArray[5] and get a string in the 6th position.

this is one usage, the others are as mentioned above, a pointer to a pointer, and can be allocated simply by:

char* str = (char*)malloc(40);
char** pointerToPointer = &str //Get the address of the str pointer, valid only in the current closure.

read more here: good array tutorial

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜