char ** questions

S

sieg1974

Hi,

I have made this simple program to understand char ** pointers, but I
still having many questions.

int main()
{
char ** testPointerPointerChar = 0;

char * A = "string01";
char * B = "string02";


if ( ( testPointerPointerChar = malloc( 50 * 256 * sizeof( char ) ) )
== NULL )
return( -1 );

/*
*( testPointerPointerChar + 0 ) = A;
*( testPointerPointerChar + 1 ) = B;
*/

strcpy( *( testPointerPointerChar + 0 ), A );
strcpy( *( testPointerPointerChar + 1 ), B );

printf( "%s\n", *( testPointerPointerChar + 0 ) );
printf( "%s\n", *( testPointerPointerChar + 1 ) );

return( 0 );
}

1. testPointerPointerChar pointer points to a matriz of pointers, and
each one of them points to a char. Right?

2. Is testPointerPointerChar = malloc(...) allocating memory for this
matriz of pointers or for the block of chars?

3. With malloc( 50 * 256 * sizeof( char ) ) ) am I allocating memory
space for 50 string of 256 characters. Right?

4. *( testPointerPointerChar + 1 ) = B seems to work fine, making the
second pointer to point to B, but why strcpy( *(
testPointerPointerChar + 1 ), B ) doesn't work? It generates a
segmentation fault when this program is executed.

5. If I need to allocated memory space for the block of 50 pointers to
char, how can I do it? Would malloc( 50 * sizeof( int ) ) work? And is
the memory used by a pointer the same as an integer?

Thanks for all the help,

Andre
 
M

Martin Ambuhl

sieg1974 said:
Hi,

I have made this simple program to understand char ** pointers, but I
still having many questions.

See if the following version of your program helps. The original is
retained after it, below. Note the parts you left out, in particular.

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

int main()
{
char **tPPC = 0;
const char *A = "string01";
const char *B = "string02";
if (!(tPPC = malloc(2 * sizeof *tPPC))) {
printf("failed to allocate space for pointers\n");
return EXIT_FAILURE;
}
if (!(tPPC[0] = malloc(1 + strlen(A)))) {
printf("failed allocating space for copy of A\n");
free(tPPC);
return EXIT_FAILURE;
}
if (!(tPPC[1] = malloc(1 + strlen(B)))) {
printf("failed allocating space for copy of B\n");
free(tPPC[0]);
free(tPPC);
return EXIT_FAILURE;
}
strcpy(tPPC[0], A);
strcpy(tPPC[1], B);
printf("%s\n", tPPC[0]);
printf("%s\n", tPPC[1]);
free(tPPC[0]);
free(tPPC[1]);
free(tPPC);
return 0;
}
 
S

Sean Kenwrick

sieg1974 said:
Hi,

I have made this simple program to understand char ** pointers, but I
still having many questions.

int main()
{
char ** testPointerPointerChar = 0;

char * A = "string01";
char * B = "string02";


if ( ( testPointerPointerChar = malloc( 50 * 256 * sizeof( char ) ) )
== NULL )
return( -1 );

/*
*( testPointerPointerChar + 0 ) = A;
*( testPointerPointerChar + 1 ) = B;
*/

strcpy( *( testPointerPointerChar + 0 ), A );
strcpy( *( testPointerPointerChar + 1 ), B );

printf( "%s\n", *( testPointerPointerChar + 0 ) );
printf( "%s\n", *( testPointerPointerChar + 1 ) );

return( 0 );
}

1. testPointerPointerChar pointer points to a matriz of pointers, and
each one of them points to a char. Right?

testPointerPointerChar is a pointer to a pointer to a char (or a pointer to
the first element of and array of pointers to chars (once the memory has
been assigned for the array).
2. Is testPointerPointerChar = malloc(...) allocating memory for this
matriz of pointers or for the block of chars?

In your code you are allocating a big block of memory and pointing
testPointerPointerChar to it.

if ( ( testPointerPointerChar = malloc( 50 * 256 * sizeof( char ) ) ) ==
NULL )

But since testPointerPointerChar is a pointer to a pointer to a char this
doesn't quite look correct at the moment (although you could quite feasibly
fill this block of memory with pointers to chars later).

3. With malloc( 50 * 256 * sizeof( char ) ) ) am I allocating memory
space for 50 string of 256 characters. Right?

You have just allocated a contiguous block of 50*256 bytes.. you haven't yet
defined how you are going to use this memory (You could put 50 null
terminated strings into it each spaced 256 bytes apart to simulate an array
of type char strings[50][256], or you could fill it with 320 pointers to
chars to simulate an array of type char * pStrings[320])
4. *( testPointerPointerChar + 1 ) = B seems to work fine, making the
second pointer to point to B, but why strcpy( *(
testPointerPointerChar + 1 ), B ) doesn't work? It generates a
segmentation fault when this program is executed.

*( testPointerPointerChar + 0 ) = A;
*( testPointerPointerChar + 1 ) = B;

Now you are defining how you are using the block of memory you have
allocated. Here you are using your block of memory as though it were an
array of pointers to chars (equivalent to char * testPointerPointer[320]).

So this is like saying

testPointerPointer[0]=A;
testPointerPointer[1]=B;

So the first 4 bytes of the memory block hold a pointer to A and the second
4 bytes of the block hold a pointer to B .

But when you do the following:

strcpy( *( testPointerPointerChar + 0 ), A );
strcpy( *( testPointerPointerChar + 1 ), B );

The first strcpy() is trying to access the first entry in your array of
pointers (char * testPointerPointer[320]). i.e testPointerPointerChar[0]
but you haven't made this point anywhere yet so it gives a segmentation
violation.

You would need to point it somewhere first: E.g.

testPointerPointerChar[0]=malloc(...);
strcpy( *( testPointerPointerChar + 0 ), A ); // note
testPointerPointerChar[0] and *(testPointerPointerChar+0) are equivalent
5. If I need to allocated memory space for the block of 50 pointers to
char, how can I do it? Would malloc( 50 * sizeof( int ) ) work? And is
the memory used by a pointer the same as an integer?

If you just want 50 pointers to chars you would do:

char * strings[50];

Then allocate memory for each string array:

strings[0]=malloc(....);
strings[1]=malloc(....);

Or you could have

char ** strings;

then

strings=malloc(50*sizeof(char *));
strings[0]=malloc(....);
strings[1]=malloc(....);

hope this helps
Sean
 
B

Barry Schwarz

Hi,

I have made this simple program to understand char ** pointers, but I
still having many questions.

int main()
{
char ** testPointerPointerChar = 0;

char * A = "string01";
char * B = "string02";


if ( ( testPointerPointerChar = malloc( 50 * 256 * sizeof( char ) ) )
== NULL )

This does not allocate the correct amount of memory. Your variable is
a pointer to pointer. Therefore, each object it points to is a
pointer to char, not a char. You need to replace sizeof(char) with
either sizeof(char*) or, preferably, sizeof *testPointerPointerChar.
Since you only use the first two pointers, this will not cause
problems in THIS code.
return( -1 );

/*
*( testPointerPointerChar + 0 ) = A;

Not incorrect but most prefer testPointerPointerChar[0] = ...
*( testPointerPointerChar + 1 ) = B;
*/

strcpy( *( testPointerPointerChar + 0 ), A );

This invokes undefined behavior. *(testPointerPointerChar+0) points
to a string literal. strcpy will attempt to replace the data in this
literal. Any attempt to modify a string literal is illegal.
strcpy( *( testPointerPointerChar + 1 ), B );

printf( "%s\n", *( testPointerPointerChar + 0 ) );
printf( "%s\n", *( testPointerPointerChar + 1 ) );

return( 0 );
}

1. testPointerPointerChar pointer points to a matriz of pointers, and
each one of them points to a char. Right?

Close. testPointerPointerChar points to the first of a sequence of
pointers which can be treated as an array or matrix. For
testPointerPointerChar to actually have the type pointer to array of
pointers, it would need to be declared as
char *(*testPointerPointerChar)[N]
2. Is testPointerPointerChar = malloc(...) allocating memory for this
matriz of pointers or for the block of chars?

For the matrix of pointers. testPointerPointerChar is a char**. The
Thing it points to is always of the same type as
*testPointerPointerChar. *(char**) is of type char*.
3. With malloc( 50 * 256 * sizeof( char ) ) ) am I allocating memory
space for 50 string of 256 characters. Right?

Not at all. Since sizeof(char) is guaranteed to be 1, you are
allocating 12,800 bytes which is capable of holding
12800/sizeof(char*) pointers. After the return from malloc, none of
these pointers is initialized so they don't point anywhere.
4. *( testPointerPointerChar + 1 ) = B seems to work fine, making the
second pointer to point to B, but why strcpy( *(
testPointerPointerChar + 1 ), B ) doesn't work? It generates a
segmentation fault when this program is executed.

A segmentation fault is one of the better manifestations of undefined
behavior. Thank your compiler writer.
5. If I need to allocated memory space for the block of 50 pointers to
char, how can I do it? Would malloc( 50 * sizeof( int ) ) work? And is

Why sizeof(int)? You are not allocating space for int. You are
allocating space for char*. Try 50 * sizeof(char*).
the memory used by a pointer the same as an integer?

That is an implementation detail. On many systems, sizeof(int) and
sizeof(char*) are both 4. BUT they are completely different types.
Be aware that if T1 and T2 are different types, there is no
requirement for sizeof(T1*) to be the same as sizeof(T2*) except in a
few special cases, such as void* and char*.


<<Remove the del for email>>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,135
Messages
2,570,784
Members
47,342
Latest member
KelseyK737

Latest Threads

Top