Reallocating char* array size

I am trying to have an array of strings, but I can't quite figure out how I'd allocate an array of strings.

What I want to do:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
char **wordlist, **responselist; int arraysizes[2] = { 3, 3 };
void increasearray()
{
	wordlist = (char**)realloc(wordlist, arraysizes[0] + 1 * 255); //Increase the amount of strings the array can hold by one.
	responselist = (char**)realloc(responselist, arraysizes[1] + 1 * 255); //Increase the amount of strings the array can hold by one.

	arraysizes[0]++;
	arraysizes[1]++;
}
void setup()
{
	wordlist = (char**)malloc(3 * 255); //Create an Array which holds 3 strings of 255 characters
	responselist = (char**)malloc(3 * 255); //Create an Array which holds 3 strings of 255 characters

	strcpy(wordlist[0], "First word!");
	strcpy(responselist[0], "First Response!");
	return;
}
int main()
{
	setup();
	/* Some Code things */
	printf("1: %s\n2: %s", wordlist[0], responselist[0]);
	increasearray();
	strcpy(wordlist[arraysizes[0]], "Second Word!");
	strcpy(responselist[arraysizes[1]], "Second Response!");
	printf("%d: %s\n%d: %s", arraysizes[0], arraysizes[1] + 1, wordlist[arraysizes[0]], responselist[arraysizes[1]]);
	printf("Done!\n");
	getch();
	return 0;
}

I have looked around and found some posts on other sites that weren't too helpful.
All things I've tried throw some sort of error. The code above throws an exceptions and I am not sure why.
vector<string> wordlist;
Well, normally I do this in C++ and as @lastchance already suggested, a vector of strings would be the way to go.

But writing in C, I'm less familiar with malloc() etc. but I think this would be a start.

I didn't study the code in function increasearray() but it would definitely require rewriting to take account of the use of pointers as in setup().


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

char **wordlist;
char **responselist; 

void setup()
{
    // Create an Array which holds 3 strings of 255 characters
    
    wordlist     = (char**)malloc(3 * sizeof(char*)); 
    responselist = (char**)malloc(3 * sizeof(char*));

    for (int i=0; i<3; ++i)
    {
        wordlist[i]     = (char*)malloc(255);
        responselist[i] = (char*)malloc(255);
    }

    strcpy(wordlist[0],     "First word!");
    strcpy(responselist[0], "First Response!");
}

void cleanup()
{
    for (int i=0; i<3; ++i)
    {
        free(wordlist[i]);
        free(responselist[i]);
    }    
   
    free(wordlist); 
    free(responselist); 
}


int main()
{
    setup();
    printf("1: %s\n2: %s\n", wordlist[0], responselist[0]);
    
    
    cleanup();
    printf("Done!\n");
    getch();
    return 0;
}
It does not need to be multiple arrays. There is a different way to make life complicated.

Fact: the program has to reserve an array of 255 characters for each string.

One could have just one array that stores N*255 characters, if one locate where each string is in the array.

Locating is easy. String k starts from character k*255 of the array.
256 is a multiple of something, while 255 is not:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define WORD 256

int word( int k )
{
    return k * WORD;
}

char * setup( const char * data )
{
    char * arr = (char*)malloc( 3 * WORD );
    strncpy( arr, data, WORD );
    arr[ word(1) - 1 ] = '\0';
    arr[ word(1) ] = '\0';
    arr[ word(2) ] = '\0';
    return arr;
}

char * increase( char * arr, int size )
{
    arr = (char*)realloc( arr, word(size)  + WORD );
    arr[ word(size) ] = '\0';
    return arr;
}

void write( char * arr, int k, const char * data )
{
    int pos = word( k );
    strncpy( arr+pos, data, WORD );
    arr[ pos + WORD - 1 ] = '\0';
}

int main()
{
    char * wordlist = 0;
    wordlist = setup( "First word!" );
    wordlist = increase( wordlist, 3 );
    write( wordlist, 3, "Hello" );

    for ( int x=0; x<4; ++x )
        printf("%d: %s\n", x+1, wordlist + word( x ) );

    free( wordlist );
    printf("Done!\n");
    return 0;
}
Actually I agree with @keskiverto, there are other ways to tackle this. That approach has some advantages.

Still, I post the following simply because I tested it and rather than throw it away, I'll put it here. It includes a version of increasearray() which builds on my previous post.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

char **wordlist;
char **responselist; 

int numrows = 3;
int numcols = 255;

void setup()
{
    // Create an Array which holds numrows strings of numcols characters
    
    wordlist     = (char**)malloc(numrows * sizeof(char*)); 
    responselist = (char**)malloc(numrows * sizeof(char*));

    for (int i=0; i<numrows; ++i)
    {
        wordlist[i]     = (char*)malloc(numcols);
        responselist[i] = (char*)malloc(numcols);
    }

    // this part optional. Set each string content to empty string ""
    for (int i=0; i<numrows; ++i)
    {
        *wordlist[i]     = '\0';
        *responselist[i] = '\0';
    }
    
    strcpy(wordlist[0],     "First word!");
    strcpy(responselist[0], "First Response!");
    
    strcpy(wordlist[numrows-1],     "Last word!");
    strcpy(responselist[numrows-1], "Last Response!");
}

void increasearray()
{
    // Increase the amount of strings the arrays can hold by one.
    
    wordlist     = (char**)realloc(wordlist,     (numrows+1) * sizeof(char*));     
    responselist = (char**)realloc(responselist, (numrows+1) * sizeof(char*));
    
    wordlist[numrows]     = (char*)malloc(numcols);
    responselist[numrows] = (char*)malloc(numcols);
    
    // this part optional. Set each string content to empty string ""
    *wordlist[numrows]     = '\0';
    *responselist[numrows] = '\0';
    
    // lastly, increase value of current array size
    ++numrows;    
}

void cleanup()
{
    for (int i=0; i<numrows; ++i)
    {
        free(wordlist[i]);
        free(responselist[i]);
    }    
   
    free(wordlist); 
    free(responselist); 
}

void printarray(char** array, int size)
{
    for (int i=0; i<size; ++i)
    {
        printf("%3d: %s\n", i+1, array[i]);
    }
    printf("\n");
}

int main()
{
    setup();

    printf("1: %s\n2: %s\n\n", wordlist[0], responselist[0]);

    printarray(wordlist, numrows);
    printarray(responselist, numrows);
    
    //-----------------------------------------

    increasearray();
    strcpy(wordlist[numrows-1], "Second Word!");
    strcpy(responselist[numrows-1], "Second response!");

    //-----------------------------------------

    increasearray();
    strcpy(wordlist[numrows-1], "Apples and Pears");
    strcpy(responselist[numrows-1], "Stairs");
        
    //-----------------------------------------

    increasearray();
    strcpy(wordlist[numrows-1], "Frog and toad");
    strcpy(responselist[numrows-1], "Road");
        
    printarray(wordlist, numrows);
    printarray(responselist, numrows);
    
    //-----------------------------------------

    cleanup();
    printf("Done!\n");
    getch();
    return 0;
}

Jumping on the bandwagon, here's a solution where wordlist and responselist point to variable length arrays where each item is itself an array of 256 chars.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <cstdlib>
#include <cstring>
#include <cstdio>

constexpr unsigned MaxStrSize = 256;

// wordlist and responselist are pointers to arrays of MaxStrSize chars
char (*wordlist)[MaxStrSize], (*responselist)[MaxStrSize];

int arraysizes[2] = {3,3};

void increasearray()
{
	arraysizes[0]++;
	arraysizes[1]++;
	wordlist = (char(*)[MaxStrSize])realloc(wordlist, arraysizes[0] * MaxStrSize);
	responselist = (char(*)[MaxStrSize])realloc(responselist, arraysizes[1] * MaxStrSize);

	// initialize with empty string
	wordlist[arraysizes[0]-1][0] = 0;
	responselist[arraysizes[1]-1][0] = 0;
}
void setup()
{
    // use calloc so each string is initialized.
    wordlist = (char(*)[MaxStrSize])calloc(arraysizes[0], MaxStrSize);
    responselist = (char(*)[MaxStrSize])calloc(arraysizes[1], MaxStrSize);
    strcpy(wordlist[0], "First word!");
    strcpy(responselist[0], "First Response!");
}

// Print both arrays of strings
void print()
{
    for (int i=0; i < arraysizes[0]; ++i) {
	printf("wordlist[%d] = \"%s\"\n", i, wordlist[i]);
    }
    for (int i=0; i < arraysizes[1]; ++i) {
	printf("responselist[%d] = \"%s\"\n", i, responselist[i]);
    }

}

int main()
{
    setup();
    print();

    increasearray();
    printf("\nAfter increase:\n");
    print();

    // The last string in wordlist is at index arraysizes[0]-1
    strcpy(wordlist[arraysizes[0]-1], "Second Word!");
    strcpy(responselist[arraysizes[1]-1], "Second Response!");

    printf("\nAfter setting last strings:\n");
    print();
}

wordlist[0] = "First word!"
wordlist[1] = ""
wordlist[2] = ""
responselist[0] = "First Response!"
responselist[1] = ""
responselist[2] = ""

After increase:
wordlist[0] = "First word!"
wordlist[1] = ""
wordlist[2] = ""
wordlist[3] = ""
responselist[0] = "First Response!"
responselist[1] = ""
responselist[2] = ""
responselist[3] = ""

After setting last strings:
wordlist[0] = "First word!"
wordlist[1] = ""
wordlist[2] = ""
wordlist[3] = "Second Word!"
responselist[0] = "First Response!"
responselist[1] = ""
responselist[2] = ""
responselist[3] = "Second Response!"



Topic archived. No new replies allowed.