Using pointers for equivalent of dynamic array of strings 
Author Message
 Using pointers for equivalent of dynamic array of strings

I am trying to create the equivalent of a 2-dimensional array of strings
using double pointers. This will be used to store the results of small sql
queries for sorting. As C requires all variables to be declared first, I
cannot know how many records will be retrieved so as to statically create
the array
i.e. *therow[Numrows][3] for example (3 fields).

The following code works as a standalone piece:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

int main() {
        int i,j;
        char *(*therow)[3];
        therow[0][0] = strcpy (malloc(5), "sven");
        therow[0][1] = strcpy (malloc(7), "Sven W");
        therow[0][2] = strcpy (malloc(7), "field3");
        therow[1][0] = strcpy (malloc(7), "george");
        therow[1][1] = strcpy (malloc(9), "George A");
        therow[1][2] = strcpy (malloc(7), "field3");

        for (i = 0; i < 2; i++) {
            for (j = 0; j < 3; j++) {
                printf ("%s\t", therow[i][j]);
                    free (therow[i][j]);
            }
            printf ("\n");
        }
        return 0;

Quote:
}

The question is what is wrong with the code. I say this because if, for
example, the int declarations are placed after the char *(*therow)[3]
declaration, the program dumps core (Bus error : arraytest.c:8 =>
therow[0][0] = strcpy.......)

Also, when this code is included in the actual program that it was intended
to be used in, the program dumps core on exit. That differs in that instead
of using therow[0][0] to assign the values, I am using a variable in the
first spot (therow[kount][0] = strcpy .... etc).

I have done some research prior to posting this and I suspect that the
problem lies in the fact that I am not allocating memory for the pointers
(char** and char* ) themselves.

Any help here would be appreciated. Again the intended effect is to create:
[record 1] {field1, field2, field3 }
[record 2] {field1, field2, field3 }
dynamically, hence the attempt to use pointers.

Thanks



Wed, 17 Aug 2005 05:39:23 GMT  
 Using pointers for equivalent of dynamic array of strings
I am trying to create the equivalent of a 2-dimensional array of strings
using double pointers. This will be used to store the results of small sql
queries for sorting. As C requires all variables to be declared first, I
cannot know how many records will be retrieved so as to statically create
the array
i.e. *therow[Numrows][3] for example (3 fields).

The following code works as a standalone piece:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

int main() {
        int i,j;
        char *(*therow)[3];
        therow[0][0] = strcpy (malloc(5), "sven");
        therow[0][1] = strcpy (malloc(7), "Sven W");
        therow[0][2] = strcpy (malloc(7), "field3");
        therow[1][0] = strcpy (malloc(7), "george");
        therow[1][1] = strcpy (malloc(9), "George A");
        therow[1][2] = strcpy (malloc(7), "field3");

        for (i = 0; i < 2; i++) {
            for (j = 0; j < 3; j++) {
                printf ("%s\t", therow[i][j]);
                    free (therow[i][j]);
            }
            printf ("\n");
        }
        return 0;

Quote:
}

The question is what is wrong with the code. I say this because if, for
example, the int declarations are placed after the char *(*therow)[3]
declaration, the program dumps core (Bus error : arraytest.c:8 =>
therow[0][0] = strcpy.......)

Also, when this code is included in the actual program that it was intended
to be used in, the program dumps core on exit. That differs in that instead
of using therow[0][0] to assign the values, I am using a variable in the
first spot (therow[kount][0] = strcpy .... etc).

I have done some research prior to posting this and I suspect that the
problem lies in the fact that I am not allocating memory for the pointers
(char** and char* ) themselves.

Any help here would be appreciated. Again the intended effect is to create:
[record 1] {field1, field2, field3 }
[record 2] {field1, field2, field3 }
dynamically, hence the attempt to use pointers.

Thanks



Wed, 17 Aug 2005 05:40:06 GMT  
 Using pointers for equivalent of dynamic array of strings
I am trying to create the equivalent of a 2-dimensional array of strings
using double pointers. This will be used to store the results of small sql
queries for sorting. As C requires all variables to be declared first, I
cannot know how many records will be retrieved so as to statically create
the array
i.e. *therow[Numrows][3] for example (3 fields).

The following code works as a standalone piece:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

int main() {
        int i,j;
        char *(*therow)[3];
        therow[0][0] = strcpy (malloc(5), "sven");
        therow[0][1] = strcpy (malloc(7), "Sven W");
        therow[0][2] = strcpy (malloc(7), "field3");
        therow[1][0] = strcpy (malloc(7), "george");
        therow[1][1] = strcpy (malloc(9), "George A");
        therow[1][2] = strcpy (malloc(7), "field3");

        for (i = 0; i < 2; i++) {
            for (j = 0; j < 3; j++) {
                printf ("%s\t", therow[i][j]);
                    free (therow[i][j]);
            }
            printf ("\n");
        }
        return 0;

Quote:
}

The question is what is wrong with the code. I say this because if, for
example, the int declarations are placed after the char *(*therow)[3]
declaration, the program dumps core (Bus error : arraytest.c:8 =>
therow[0][0] = strcpy.......)

Also, when this code is included in the actual program that it was intended
to be used in, the program dumps core on exit. That differs in that instead
of using therow[0][0] to assign the values, I am using a variable in the
first spot (therow[kount][0] = strcpy .... etc).

I have done some research prior to posting this and I suspect that the
problem lies in the fact that I am not allocating memory for the pointers
(char** and char* ) themselves.

Any help here would be appreciated. Again the intended effect is to create:
[record 1] {field1, field2, field3 }
[record 2] {field1, field2, field3 }
dynamically, hence the attempt to use pointers.

Thanks

Sven Willenberger
remove dot nospam in replies



Wed, 17 Aug 2005 05:42:07 GMT  
 Using pointers for equivalent of dynamic array of strings
I am trying to create the equivalent of a 2-dimensional array of strings
using double pointers. This will be used to store the results of small sql
queries for sorting. As C requires all variables to be declared first, I
cannot know how many records will be retrieved so as to statically create
the array
i.e. *therow[Numrows][3] for example (3 fields).

The following code works as a standalone piece:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

int main() {
        int i,j;
        char *(*therow)[3];
        therow[0][0] = strcpy (malloc(5), "sven");
        therow[0][1] = strcpy (malloc(7), "Sven W");
        therow[0][2] = strcpy (malloc(7), "field3");
        therow[1][0] = strcpy (malloc(7), "george");
        therow[1][1] = strcpy (malloc(9), "George A");
        therow[1][2] = strcpy (malloc(7), "field3");

        for (i = 0; i < 2; i++) {
            for (j = 0; j < 3; j++) {
                printf ("%s\t", therow[i][j]);
                    free (therow[i][j]);
            }
            printf ("\n");
        }
        return 0;

Quote:
}

The question is what is wrong with the code. I say this because if, for
example, the int declarations are placed after the char *(*therow)[3]
declaration, the program dumps core (Bus error : arraytest.c:8 =>
therow[0][0] = strcpy.......)

Also, when this code is included in the actual program that it was intended
to be used in, the program dumps core on exit. That differs in that instead
of using therow[0][0] to assign the values, I am using a variable in the
first spot (therow[kount][0] = strcpy .... etc).

I have done some research prior to posting this and I suspect that the
problem lies in the fact that I am not allocating memory for the pointers
(char** and char* ) themselves.

Any help here would be appreciated. Again the intended effect is to create:
[record 1] {field1, field2, field3 }
[record 2] {field1, field2, field3 }
dynamically, hence the attempt to use pointers.

Thanks

Sven Willenberger
remove dot nospam in replies



Wed, 17 Aug 2005 05:43:19 GMT  
 Using pointers for equivalent of dynamic array of strings
I am trying to create the equivalent of a 2-dimensional array of
strings using double pointers. This will be used to store the results
of small sql queries for sorting. As C requires all variables to be
declared first, I cannot know how many records will be retrieved so as
to statically create the array
i.e. *therow[Numrows][3] for example (3 fields).

The following code works as a standalone piece:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

int main() {
        int i,j;
        char *(*therow)[3];
        therow[0][0] = strcpy (malloc(5), "sven");
        therow[0][1] = strcpy (malloc(7), "Sven W");
        therow[0][2] = strcpy (malloc(7), "field3");
        therow[1][0] = strcpy (malloc(7), "george");
        therow[1][1] = strcpy (malloc(9), "George A");
        therow[1][2] = strcpy (malloc(7), "field3");

        for (i = 0; i < 2; i++) {
            for (j = 0; j < 3; j++) {
                printf ("%s\t", therow[i][j]);
                    free (therow[i][j]);
            }
            printf ("\n");
        }
        return 0;

Quote:
}

The question is what is wrong with the code. I say this because if,
for example, the int declarations are placed after the char
*(*therow)[3] declaration, the program dumps core (Bus error :
arraytest.c:8 => therow[0][0] = strcpy.......)

Also, when this code is included in the actual program that it was
intended to be used in, the program dumps core on exit. That differs
in that instead of using therow[0][0] to assign the values, I am using
a variable in the first spot (therow[kount][0] = strcpy .... etc).

I have done some research prior to posting this and I suspect that the
problem lies in the fact that I am not allocating memory for the
pointers (char** and char* ) themselves.

Any help here would be appreciated. Again the intended effect is to
create:
[record 1] {field1, field2, field3 }
[record 2] {field1, field2, field3 }
dynamically, hence the attempt to use pointers.

Thanks



Wed, 17 Aug 2005 05:44:46 GMT  
 Using pointers for equivalent of dynamic array of strings

Quote:

> I am trying to create the equivalent of a 2-dimensional array of strings
> using double pointers.

Dammit, stop posting this.  I've seen it three times in the last
two minutes.
--
"Debugging is twice as hard as writing the code in the first place.
 Therefore, if you write the code as cleverly as possible, you are,
 by definition, not smart enough to debug it."
--Brian Kernighan


Wed, 17 Aug 2005 05:43:18 GMT  
 Using pointers for equivalent of dynamic array of strings

Quote:

> int main() {
>         int i,j;
>         char *(*therow)[3];

`therow' is a pointer to an array of 3 pointers to chars.

Quote:
>         therow[0][0] = strcpy (malloc(5), "sven");

Here you are using `therow' without initializing it.  That's
undefined behavior for a pointer just as it is for any other kind
of variable.  You need to allocate some memory for therow and
assign that memory to it.

[...]

Quote:
> }

--
"I'm not here to convince idiots not to be stupid.
 They won't listen anyway."
--Dann Corbit


Wed, 17 Aug 2005 05:41:57 GMT  
 Using pointers for equivalent of dynamic array of strings
I apologize for the multiple posts .... my client decided to cop an attitude


Wed, 17 Aug 2005 05:51:48 GMT  
 Using pointers for equivalent of dynamic array of strings


Quote:

> > int main() {
> >         int i,j;
> >         char *(*therow)[3];

> `therow' is a pointer to an array of 3 pointers to chars.

Which is correct for what I want to do, yes?

Quote:

> >         therow[0][0] = strcpy (malloc(5), "sven");

> Here you are using `therow' without initializing it.  That's
> undefined behavior for a pointer just as it is for any other kind
> of variable.  You need to allocate some memory for therow and
> assign that memory to it.

Which is what I suspected (and noted). So the question is the proper format
for this:
therow =  (char **) malloc (sizeof(char **));
???
everything I have come across would indicate something similar to the above
but they often include  malloc (N * sizeof(char**)) which, would seem to
indicate that I need to know what N is. Now if this needs to be 3 (for the 3
"fields") I would use:
therow = (char **) malloc (3 * sizeof(char**));
??

Quote:

> > }

I apologize for the multiple posts earlier, my new client was having issues
(which as it turns out did involve a little 1d10t error as well) but has
been fixed.

Thanks,

Sven



Wed, 17 Aug 2005 06:02:50 GMT  
 Using pointers for equivalent of dynamic array of strings

Quote:




> > > int main() {
> > >         int i,j;
> > >         char *(*therow)[3];

> > `therow' is a pointer to an array of 3 pointers to chars.

> Which is correct for what I want to do, yes?

> > >         therow[0][0] = strcpy (malloc(5), "sven");

> > Here you are using `therow' without initializing it.  That's
> > undefined behavior for a pointer just as it is for any other kind
> > of variable.  You need to allocate some memory for therow and
> > assign that memory to it.

> Which is what I suspected (and noted). So the question is the proper format
> for this:
> therow =  (char **) malloc (sizeof(char **));

No, you need to allocate a number of arrays of 3 pointers to
chars, e.g., char *[3].  That's quite different from char **.
The former is (an array of) single pointers, the latter is a
double pointer.

When calling malloc(), I recommend using the sizeof operator on
the object you are allocating, not on the type.  For instance,
*don't* write this:

        int *x = malloc (sizeof (int) * 128); /* Don't do this! */

Instead, write it this way:

        int *x = malloc (sizeof *x * 128);

There's a few reasons to do it this way:

        * If you ever change the type that `x' points to, it's not
          necessary to change the malloc() call as well.

          This is more of a problem in a large program, but it's still
          convenient in a small one.

        * Taking the size of an object makes writing the statement
          less error-prone.  You can verify that the sizeof syntax is
          correct without having to look at the declaration.

I don't recommend casting the return value of malloc():

        * The cast is not required in ANSI C.

        * Casting its return value can mask a failure to #include
          <stdlib.h>, which leads to undefined behavior.

        * If you cast to the wrong type by accident, odd failures can
          result.

Quote:
> everything I have come across would indicate something similar to the above
> but they often include  malloc (N * sizeof(char**)) which, would seem to
> indicate that I need to know what N is. Now if this needs to be 3 (for the 3
> "fields") I would use:
> therow = (char **) malloc (3 * sizeof(char**));

You seem to be conflating multiple concepts here.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
 \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}


Wed, 17 Aug 2005 06:07:36 GMT  
 Using pointers for equivalent of dynamic array of strings

Quote:

> I apologize for the multiple posts .... my client decided to cop an attitude

That's what you get for using crappy Outlook.

--
 josh(at)cc.gatech.edu  |  http://intmain.net:800

 415385 local keystrokes since last reboot (37 days ago)



Wed, 17 Aug 2005 10:18:58 GMT  
 Using pointers for equivalent of dynamic array of strings

Quote:

> > > > int main() {
> > > >         int i,j;
> > > >         char *(*therow)[3];

> > > `therow' is a pointer to an array of 3 pointers to chars.

> > Which is correct for what I want to do, yes?

> > > >         therow[0][0] = strcpy (malloc(5), "sven");

> > > Here you are using `therow' without initializing it.  That's
> > > undefined behavior for a pointer just as it is for any other kind
> > > of variable.  You need to allocate some memory for therow and
> > > assign that memory to it.

> > Which is what I suspected (and noted). So the question is the proper
format
> > for this:
> > therow =  (char **) malloc (sizeof(char **));

> No, you need to allocate a number of arrays of 3 pointers to
> chars, e.g., char *[3].  That's quite different from char **.
> The former is (an array of) single pointers, the latter is a
> double pointer.

> When calling malloc(), I recommend using the sizeof operator on
> the object you are allocating, not on the type.  For instance,
> *don't* write this:

> int *x = malloc (sizeof (int) * 128); /* Don't do this! */

> Instead, write it this way:

> int *x = malloc (sizeof *x * 128);

> There's a few reasons to do it this way:

> * If you ever change the type that `x' points to, it's not
>           necessary to change the malloc() call as well.

>   This is more of a problem in a large program, but it's still
>   convenient in a small one.

> * Taking the size of an object makes writing the statement
>           less error-prone.  You can verify that the sizeof syntax is
>           correct without having to look at the declaration.

Thanks for the tips .... this eliminated the core dumps (and helped clarify
some pointer issues a little - although not completely as the next section
will illustrate):

The problem: When dynamically filling the "array", I end up with junk data
in the lower iterations. The following code (wherein I create a small loop
of 5 and fill the same data) produces the subsequent output. The higher the
loop count, the more "rows" end up with the junk data. I suspect I missed
the boat in allocating the data, but at this point (a couple days later) I
am at a loss (it's as if junk data is getting "pushed" on the memory
location occupied by the "therow[x][y]" or that the pointer is changing) ...

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

int main() {
        char *(*therow)[3];
        int i,j,k;
        therow =  malloc (sizeof ((*therow)[3]));
        printf ("The size of therow = %d with address %x\n", (int)
sizeof(therow), (unsigned int) &therow);
        for (k = 0; k < 5; k++) {
                therow[k][0] = strcpy (malloc(13), "sven is here");
                therow[k][1] = strcpy (malloc(7), "Sven W");
                therow[k][2] = strcpy (malloc(8), "dmv.com");
                printf ("therow[0][0] = %s \(length %d)\n", therow[0][0],
strlen (therow[0][0]));
        }
        for (i = 0; i < 5; i++) {
                printf ("Iteration %d\n", i);
                for (j = 0; j < 3; j++) {
                        printf("%s\( address = %x and length = %d)\t\n",
therow[i][j], (unsigned int) &therow[i][j], strlen(therow[i][j]));
                        free (therow[i][j]);
                }
                printf ("\n");
        }
        free (therow);
        return 0;

Quote:
}

OUTPUT =>

The size of therow = 4 with address bfbffb84
therow[0][0] = sven is here (length 12)
therow[0][0] = ? here (length 12)
therow[0][0] = ?   W (length 22)
therow[0][0] = ?  Dedmv.com (length 39)
therow[0][0] = ?  De (length 32)
Iteration 0
?  De( address = 804b030 and length = 32)
De( address = 804b034 and length = 16)
( address = 804b038 and length = 0)

Iteration 1
sven is here( address = 804b03c and length = 12)
Sven W( address = 804b040 and length = 6)
dmv.com( address = 804b044 and length = 7)

Iteration 2
sven is here( address = 804b048 and length = 12)
Sven W( address = 804b04c and length = 6)
dmv.com( address = 804b050 and length = 7)

Iteration 3
sven is here( address = 804b054 and length = 12)
Sven W( address = 804b058 and length = 6)
dmv.com( address = 804b05c and length = 7)

Iteration 4
sven is here( address = 804b060 and length = 12)
Sven W( address = 804b064 and length = 6)
dmv.com( address = 804b068 and length = 7)

********************************
Sven Willenberger
[remove dot nospam in any personal replies]



Fri, 19 Aug 2005 21:45:32 GMT  
 Using pointers for equivalent of dynamic array of strings


Quote:


> > > > > int main() {
> > > > >         int i,j;
> > > > >         char *(*therow)[3];

> > > > `therow' is a pointer to an array of 3 pointers to chars.

> > > Which is correct for what I want to do, yes?

> > > > >         therow[0][0] = strcpy (malloc(5), "sven");

> > > > Here you are using `therow' without initializing it.  That's
> > > > undefined behavior for a pointer just as it is for any other kind
> > > > of variable.  You need to allocate some memory for therow and
> > > > assign that memory to it.

> > > Which is what I suspected (and noted). So the question is the proper
> format
> > > for this:
> > > therow =  (char **) malloc (sizeof(char **));

> > No, you need to allocate a number of arrays of 3 pointers to
> > chars, e.g., char *[3].  That's quite different from char **.
> > The former is (an array of) single pointers, the latter is a
> > double pointer.

> > When calling malloc(), I recommend using the sizeof operator on
> > the object you are allocating, not on the type.  For instance,
> > *don't* write this:

> > int *x = malloc (sizeof (int) * 128); /* Don't do this! */

> > Instead, write it this way:

> > int *x = malloc (sizeof *x * 128);

> > There's a few reasons to do it this way:

> > * If you ever change the type that `x' points to, it's not
> >           necessary to change the malloc() call as well.

> >   This is more of a problem in a large program, but it's still
> >   convenient in a small one.

> > * Taking the size of an object makes writing the statement
> >           less error-prone.  You can verify that the sizeof syntax is
> >           correct without having to look at the declaration.

> Thanks for the tips .... this eliminated the core dumps (and helped
clarify
> some pointer issues a little - although not completely as the next section
> will illustrate):

> The problem: When dynamically filling the "array", I end up with junk data
> in the lower iterations. The following code (wherein I create a small loop
> of 5 and fill the same data) produces the subsequent output. The higher
the
> loop count, the more "rows" end up with the junk data. I suspect I missed
> the boat in allocating the data, but at this point (a couple days later) I
> am at a loss (it's as if junk data is getting "pushed" on the memory
> location occupied by the "therow[x][y]" or that the pointer is changing)
...

> #include <stdio.h>
> #include <stdlib.h>
> #include <strings.h>

> int main() {
>         char *(*therow)[3];
>         int i,j,k;
>         therow =  malloc (sizeof ((*therow)[3]));
>         printf ("The size of therow = %d with address %x\n", (int)
> sizeof(therow), (unsigned int) &therow);
>         for (k = 0; k < 5; k++) {
>                 therow[k][0] = strcpy (malloc(13), "sven is here");
>                 therow[k][1] = strcpy (malloc(7), "Sven W");
>                 therow[k][2] = strcpy (malloc(8), "dmv.com");
>                 printf ("therow[0][0] = %s \(length %d)\n", therow[0][0],
> strlen (therow[0][0]));
>         }
>         for (i = 0; i < 5; i++) {
>                 printf ("Iteration %d\n", i);
>                 for (j = 0; j < 3; j++) {
>                         printf("%s\( address = %x and length = %d)\t\n",
> therow[i][j], (unsigned int) &therow[i][j], strlen(therow[i][j]));
>                         free (therow[i][j]);
>                 }
>                 printf ("\n");
>         }
>         free (therow);
>         return 0;
> }

Just found the answer ... when allocated memory for "therow" itself, it
needs some dimension. At that point I know the number of rows returned by my
SQL so:
therow =  malloc (NUM_ROWS * sizeof ((*therow)[3]));
works fine :-)

Sven Willenberger
[remove dot nospam in any personal replies]



Fri, 19 Aug 2005 22:49:30 GMT  
 
 [ 13 post ] 

 Relevant Pages 

1. Copy Array string to another Pointer array string in ANSI-C

2. Display string without using array or pointers.

3. Pointer to Array of Pointers to Strings.

4. convert list to array, arrays of pointers (to strings)

5. How To pass 2D String array to VB from VC++ Using Safe array

6. Dynamic Array of pointer memory allocation

7. dynamic array of pointers

8. dynamic pointer array to struct

9. Dynamic Array of Smart Pointer?

10. Function returns pointer to dynamic array

11. Dynamic array of pointers confusion

12. Dynamic allocation of pointer arrays

 

 
Powered by phpBB® Forum Software