我要做的是创建一个二维字符串数组 以下seg故障,什么是错误的?
void add2(char***b, char *i)
{
if (!i) {
b[0][0] = (char*) malloc(120);
sprintf(b[0][0], "%s", "hithere");
b[0][1] = (char*) malloc(120);
sprintf(b[0][1], "%s", "bithere");
} else {
strcat(b[0][0], "\\\\");
strcat(b[0][0], i);
strcat(b[0][1], "\\\\");
strcat(b[0][1], i);
}
}
void add1(char ***b)
{
add2(b,NULL);
add2(b,"one");
add2(b,"two");
add2(b,"three");
}
int main()
{
char **keys[2] = {0};
int i,j;
add1(keys);
for (i = 0; keys[i]; i++)
for (j = 0; keys[j]; j++)
{
fprintf(stderr, "%s\n", keys[i][j]);
free(keys[i][j]);
}
}
答案 0 :(得分:2)
当您声明数组键时,您要对编译器说,您希望使用指向字符指针的2个指针数组,并要求它将指向char的指针初始化为NULL。 一切都很好。
然后你致电add1()
。 一切都很好。
然后,您致电add2()
并尝试将b[0]
的第一个元素放入malloc()
的返回值。但b[0]
的值为NULL。 NULL被放在main()
函数中。 b[0]
没有元素!
如果你有数组数组(数组......) 以指针形式,你需要malloc()
(和free()
)每个级别单独。
修改的
#include <stdlib.h>
int main()
{
char **keys[2] = {0};
keys[0] = malloc(20 * sizeof *keys[0]); /* 20 strings */
keys[1] = malloc(20 * sizeof *keys[1]); /* 20 strings */
for (int k=0; k<20; k++) {
keys[0][k] = malloc(120); /* string with 119 chars + '\0' */
keys[1][k] = malloc(120); /* string with 119 chars + '\0' */
}
/* use k[0][0] through k[0][19] */
/* use k[1][0] through k[1][19] */
for (int k=0; k<20; k++) {
free(keys[0][k]);
free(keys[1][k]);
}
free(keys[0]);
free(keys[1]);
return 0;
}
我把它全部放在main()
函数中,但如果malloc()
和free()
s在它们自己的函数中,那就是同样的想法。
答案 1 :(得分:1)
动态分配char *
的2D数组的一般过程是这样的(对于任何其他类型T,用所需类型替换char *
):
char ***new2DArr(size_t rows, size_t cols)
{
char ***newArr = NULL;
size_t i;
newArr = malloc(sizeof *newArr * rows);
if (newArr)
{
for (i = 0; i < rows; i++)
{
newArr[i] = malloc(sizeof *newArr[i] * cols);
if (newArr[i])
{
/* initialize or assign newArr[i][0] - newArr[i][cols-1] here */
}
}
}
return newArr;
}
这假设您提前了解了多少行和列。请注意,您已经分配了一个指针表;你仍然需要为每个字符串条目分配内存,如下所示:
char **myArr = new2DArr(10, 10);
myArr[0][0] = malloc(strlen("Hello, World") + 1);
if (myArr[0][0])
{
strcpy(myArr[0][0], "Hello, World");
}
如果要向现有行添加新行或新条目,则需要进行一些额外的簿记。
以下是扩展单行的一个示例:
char **extendRow(char **row, char *newEntry, size_t *numEntries)
{
char **tmp = realloc(row, *numEntries + 1);
if (tmp)
{
row = tmp;
row[*numEntries] = malloc(strlen(newEntry) + 1);
if (row[*numEntries])
{
strcpy(row[*numEntries], newEntry);
(*numEntries)++;
}
}
return row;
}
你称之为
table[i] = extendRow(table[i], "This is a test", &entryCount);
如果指针值被table[i]
更改,则会将结果分配回realloc()
。我这样做而不是传递一个指向table [i]的指针,只是为了将指针体操保持在最低限度。