Re: char *arr[n] Vs. char **arr



yogeshmk wrote:
I'm pasting the changed code

if ((tok = strtok(argv[1], delim)) != NULL)
{
format = (char**)malloc(1*sizeof(char*));

Why not just write:
format = malloc(sizeof *format);

Here, format is a char **
*format is a char *
**format is a char

So, sizeof *format == sizeof (char*)

if((format[i]=(char*)malloc(strlen(tok)+1)) != NULL)
strcpy((char*)format+i, tok);

This is wrong! The fact that you needed a cast should be a big red flag, indicating to you that what you are typing is wrong!

You don't want to copy to format+i. That's the start of the format array, which can only hold sizeof(char*), probably just 4 bytes.

You want to copy to format[i]. That's the memory that you just allocated with malloc.

}
/*
* gdb shows the first token copied at 0th location of format .
*/

As it should -- you told strcpy to copy there. Unfortunately you probably also copied to some bytes past what was allocated to format, which you had no right to write to.

for (i=1; tok; i++)
{
if ((tok = strtok(NULL, delim)) != NULL)
if (format = (char**)realloc(format, (i+1)*sizeof(char*))
!= NULL)

Please, for the love of God, get rid of the casts!

What you have written in the line above will work, but it's best practise to send the result of realloc to a separate temporary variable, so that if realloc fails, you don't lose your pointer to the original array.

I would write:
char **temp;
if(temp = realloc(format, (i+1) * sizeof *format)) != NULL)
{
format = temp;
...
}
else /* realloc failed */
{
return format;
}


if((format[i]=(char*)malloc(strlen(tok)+1)) != NULL)
strcpy((char*)format+i, tok);

Again, this should be strcpy(format[i], tok);

}

realloc() changes the address of format (something like 0x1) and
subsequent malloc() fails giving a segfault. Still scratching my head!
What's wrong in the code?

realloc often changes the address. This is how it usually works: it first allocates a new block of memory, then copies the contents of the old block into the new block, then returns the address of the new block.

The subsequent malloc fails because you wrote too far into the memory allocated for format, clobbering the special data structures that are used by the memory allocation system to keep track of your memory allocations.

If you fix the bug with the strcpy, it should work.

--
Simon.
.



Relevant Pages

  • Re: Here is my full program excluding the search and delete functions
    ... There is a mismatch between your format specifications and the ... &ID has type pointer to array of 50 int, ... %s requires a char*. ... >empty, empty); ...
    (comp.lang.c)
  • Re: structure
    ... > char a:4; ... if the compiler does not support ... to match an internal data structure to some external data format ... as the internal representation. ...
    (comp.lang.c)
  • "Type-safe" sprintf
    ... I have invented a simple sprintf-like function aimed at replacing sprintf. ... Char* buffer; ... Might be the format string ... feeder& operator% ...
    (microsoft.public.vc.language)
  • Re: "Type-safe" sprintf
    ... I have invented a simple sprintf-like function aimed at replacing sprintf. ... Char* buffer; ... Might be the format string ... feeder& operator% ...
    (microsoft.public.vc.language)
  • Re: Watcom vs. gcc/icl/cl difference
    ... fputs((const char *)&buffer, echoFP); ... static void out(int opt, const char * format, ...) ... /* Invalid flags given? ...
    (comp.lang.c)