22

I'm am trying to write a program that reads in a series of strings from a text file and stores these in an array of strings, dynamically allocating memory for each element. My plan was to store each string in an array using a pointer and then grow the array size as more were read in. I am having trouble to understand why my test code below is not working. Is this a workable idea?

char *aPtr;
aPtr =(char*)malloc(sizeof(char));

aPtr[0]="This is a test";


printf("%s",aPtr[0]);
alk
  • 66,653
  • 10
  • 83
  • 219
user2826534
  • 223
  • 1
  • 2
  • 4
  • 1
    This doesn't work because you `malloc` space for a single character, and then you try to assign a whole string to a `char`-typed lvalue. – Fred Foo Sep 28 '13 at 15:44
  • Recommended reading: [When should I use malloc in C and when don't I?](http://stackoverflow.com/a/1963812/2455888). – haccks Sep 28 '13 at 15:47

4 Answers4

23

In C a string is a char*. A dynamic array of type T is represented as a pointer to T, so for char* that would be char**, not simply a char* the way you declared it.

The compiler, no doubt, has issued some warnings about it. Pay attention to these warnings, very often they help you understand what to do.

Here is how you can start your testing:

char **aPtr;
int len = 1; // Start with 1 string
aPtr = malloc(sizeof(char*) * len); // Do not cast malloc in C
aPtr[0] = "This is a test";
printf("%s",aPtr[0]); // This should work now.
Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399
  • To verify (please bear with me, I'm a newbie =] ), if you wanted a dynamic array of pointers to char (e.g., as needed in an application where you may need to store a variable number character strings e.g, from reading a text file without knowing its length or gathering user input of unspecified length), then you'd need a dynamic array of Char* and so you'd need a Char**. The char** may point to different character pointers, which may be the starting address of different character strings. – Minh Tran Sep 12 '15 at 18:51
  • what is the `len=1` here for? It looks like `This is a test` would be 14 characters, which is each a byte.... but this code doesn't mention 14, nor does it segfault when I run. – nmz787 Feb 08 '17 at 00:09
  • @nmz787 Note the type of `aPtr`, it's a double-pointer, so represents an array of char pointers. A char pointer is then set into element zero; no string copying is happening in this code. – Sergey Kalinichenko Feb 08 '17 at 01:01
10
char *str; //single pointer   

With this you can store one string.


To store array of strings you Need two dimensional character array

or else array of character pointers or else double pointer


char str[10][50]; //two dimensional character array

If you declare like this you need not allocate memory as this is static declaration


char *str[10];  //array of pointers 

Here you need to allocate memory for each pointer

loop through array to allocate memory for each pointer

for(i=0;i<10;i++) 
str[i]=malloc(SIZE);

char **str;    //double pointer

Here you need to allocate memory for Number of pointers and then allocate memory for each pointer .

str=malloc( sizeof(char *)*10);

And then loop through array allocate memory for each pointer

for(i=0;i<10;i++) 
str[i]=malloc(SIZE);
Gangadhar
  • 9,510
  • 3
  • 27
  • 48
5
char * aPtr;

is as pointer to a character, to which you allocated memory to hold exactly 1 character.

Doing

aPrt[0] = "test";

you address the memory for this one characters and try to store the address of the literal "test" to it. This will fail as this address most likley is wider then a character.

A fix to your code would be to allocate memory for a pointer to a character.

char ** aPtr = malloc(sizeof(char *));
aPtr[0] = "test";
printf("%s", aPtr[0]);

Are more elegant and more over robust approach would be to allocate the same (as well as adding the mandatory error checking) by doing:

char ** aPtr = malloc(sizeof *aPtr);
if (NULL == aPtr)
{
  perror("malloc() failed");
  exit(EXIT_FAILURE);
}

...
alk
  • 66,653
  • 10
  • 83
  • 219
-1

You are doing it totally wrong. The correct version of your code should be like this:

int main ()
{
char *aPtr;
aPtr =(char*)malloc(20*sizeof(char));
aPtr ="This is a test";
printf("%s",aPtr);
}

You can use pointer array. if you want to store multiple string. Yes I know using for loop will be easy. But I am trying to explain in simple way even a beginner can understand.

int main ()
{
char *aPtr[10];
aPtr[0] =(char*)malloc(20*sizeof(char));
aPtr[0] ="This is a test";
aPtr[1] =(char*)malloc(20*sizeof(char));
aPtr[1] ="This is a test2";
printf("%s\n%s\n",aPtr[0],aPtr[1]);
 }
Tonmoy
  • 529
  • 2
  • 4
  • 17
  • Your first example leaks memory, namely 20 bytes. Doing `aPtr ="This is a test";` you lose the reference to what `malloc()` returned. This memory had never been used and will never be used during the live time of the program. – alk Sep 28 '13 at 16:27
  • `sizeof(char)`is `1` be defintion. Casting the result of `malloc/calloc/realloc` in not necessary in C nor recommended: http://stackoverflow.com/a/605858/694576 – alk Sep 28 '13 at 16:29
  • Thanks to everyone who replied it was a great help – user2826534 Sep 29 '13 at 11:29