How to dynamically allocate an array of strings

  • #1
179
6

Main Question or Discussion Point

I was supposed to write a program that has a while loop in which two people, person1 and person2 input a string. The program runs the loop until one of the people inputs "it's over". At that time the program should exit and print out the correspodance between these two people while they were in a loop.(Formatted so that you can see what they wrote and not all combined together). For that it should use a dynamically aloocated array of strings (something like char **corr, using double pointers)
Below is the code without the memorization of the correspondance.
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
  int counter = 0;
  while (1) {
     char *person1, *person2, c;
     int i = 0;
    person1 = (char*)calloc(500, sizeof(char));
    person2 = (char*)calloc(500, sizeof(char));
    printf("The person1 says: \n");
    while ( (c = getchar()) != '\n') {
      person1[i++] = c;
    }
    person1[i] = '\0';
    i = 0;
    printf("The person2 says: \n");
    while ( (c= getchar()) != '\n') {
      person2[i++] = c;
    }
    person2[i] = '\0';
   
    person1 = realloc(person1, (strlen(person1)+1)*sizeof(char));   //Freeing up unused space
    person2 = realloc(person2, (strlen(person2)+1)*sizeof(char));
   
   
        if (strcmp(person1, "it's over") == 0) {
            printf("The ending. The program will exit. \n");
            system("pause");
            break;
        }
        if (strcmp(person2, "it's over") == 0) {
            printf("The ending. The program will exit. \n");
            system("pause");
            break;
        }
        free(person1);
        free(person2);
        counter += 1;
  }
  printf("%d", counter);  \\number of times each of them sent a message.
}
I've never used ** pointer before but know that its an array of pointers. Do i now create two ** char elements to hold the conversation for each and how would i print them? How would i know when the other one finished his sentence? Do pointers in an array of pointers (char **some_name) point to strings or chars?
 

Answers and Replies

  • #2
727
168
The pointer points to an element of type char. To get a string you allocate memory to the pointer of type char and length l which is the length of the string.
 
  • Like
Likes doktorwho
  • #3
474
66
You'll need something like this:
C:
int counter=0;
const char **corr=(const char **)calloc(2*sizeof(const char*));
while(1) {
  //input as before
  //realloc as before
  //test for end as before
    //now make room for 2 more lines:
  corr=(const char **)realloc(corr, 2*(counter+1)*sizeof(const char*));
  corr[2*counter]=person1;
  corr[2*counter+1]=person2;
  //do not free person1 and person2 yet
  counter++;
}
for (int i=0; i<2*counter; i++) {
  printf("%s", corr[i]); //you'll want some more formatting here
  free(corr[i]); //free it while we're at it
}
free(corr);
I'd use an array of struct { const char *p1, *p2; } instead of flat array of char * but if you have to do it that way then I did.

Also I'd keep allocated count and used count instead of just one count, and allocate some 10 items more, and only realloc when that runs out.
Memory allocation is generally slow and also causes trouble if the application is going to run for a long time. But that's not a problem here so it should work fine as it is.
 
  • Like
Likes doktorwho
  • #4
179
6
You'll need something like this:
C:
int counter=0;
const char **corr=(const char **)calloc(2*sizeof(const char*));
while(1) {
  //input as before
  //realloc as before
  //test for end as before
    //now make room for 2 more lines:
  corr=(const char **)realloc(corr, 2*(counter+1)*sizeof(const char*));
  corr[2*counter]=person1;
  corr[2*counter+1]=person2;
  //do not free person1 and person2 yet
  counter++;
}
for (int i=0; i<2*counter; i++) {
  printf("%s", corr[i]); //you'll want some more formatting here
  free(corr[i]); //free it while we're at it
}
free(corr);
I'd use an array of struct { const char *p1, *p2; } instead of flat array of char * but if you have to do it that way then I did.

Also I'd keep allocated count and used count instead of just one count, and allocate some 10 items more, and only realloc when that runs out.
Memory allocation is generally slow and also causes trouble if the application is going to run for a long time. But that's not a problem here so it should work fine as it is.
Wow thanks a lot! Only one question. When do i then free person1 and person2? They need to be freed before the while loop goes on again, right?
 
  • #5
474
66
Wow thanks a lot! Only one question. When do i then free person1 and person2? They need to be freed before the while loop goes on again, right?
No. If you freed them, you could not print them after the conversation ends.
You need to free them after you print them.
 
  • #6
jim mcnamara
Mentor
3,912
2,306
Re: casting the variable corr to const char **.

If you turn on compiler warnings you will get clearer complaints. const implies that you guarantee no changes ever to the buffer. Which is not true, if I understand what you are doing.
 
  • #7
474
66
Re: casting the variable corr to const char **.

If you turn on compiler warnings you will get clearer complaints. const implies that you guarantee no changes ever to the buffer. Which is not true, if I understand what you are doing.
const char ** means that the characters are not modified, but the pointers and the array can (we could not do corr[0][0]='a'; )
char *const * means that the pointers cannot be modified (we do that during corr[2*count]=person1; )
char ** const means that the array cannot be modified (we do that during realloc).
So it should be fine the way it is.
 

Related Threads on How to dynamically allocate an array of strings

Replies
10
Views
5K
Replies
8
Views
2K
  • Last Post
Replies
3
Views
1K
  • Last Post
Replies
1
Views
2K
Replies
6
Views
4K
Replies
3
Views
3K
Replies
12
Views
1K
Replies
9
Views
2K
Replies
34
Views
2K
Top