我在C中处理一维和二维动态分配的数组时遇到了问题。我发现了类似的问题,但是他们都没有帮助我,所以我要问一个新问题。 / p>
这是我的问题。使用下面的函数,我想在二维char数组中添加一个新元素。大小不是问题,我在外面增加。
void addElem(char ***tabs, int size, char *new) {
*tabs[size] = (char*)malloc(sizeof(char)*strlen(new));
*tabs[size] = new;
*tabs = (char **)realloc(*tabs, size * sizeof(char *));
}
在代码中,函数以这种方式调用:
int i;
char *tmp;
char **array = (char **)malloc(sizeof(char *));
//some stuff, also initializing i and tmp
addElem(&array, i, tmp);
问题是该函数即使分配数据,也不会保存任何数据(例如,strcmp使用**数组给出SIGSEGV)。在调试类似的函数(管理one-dim int数组)时,我发现它们实际上在这些函数中正常工作,返回后数据就没有保存。
我试图尽可能少地显示代码,但如果它有助于here是完整代码(将addElem函数重命名为dodajDoTablicySlow)。感谢。
答案 0 :(得分:3)
考虑您的addElem()
功能:
void addElem(char ***tabs, int size, char *new) {
*tabs[size] = (char*)malloc(sizeof(char)*strlen(nowy));
*tabs[size] = new;
*tabs = (char **)realloc(*tabs, size * sizeof(char *));
}
此功能不会在您认为的情况下写入新元素。数组下标运算符([]
)的优先级高于间接运算符(*
),因此*tabs[size]
表示"数组size
指向的内容tabs
",不" size
"指向的数组tabs
。
此外,如果size
是动态数组的当前大小 - 如char *
成员*tabs
的数量可容纳的空间 - 那么(*tabs)[size]
是超出其能力。即使它要求有足够的空间来包含该位置,它也不会保证realloc()
调用不会保证扩展为*tabs
分配的内存以包含该空间。将新分配放在其他地方是完全免费的。当新尺寸大于旧尺寸时,有时可能需要这样做,但即使新尺寸较小,也可以自由地这样做。在某些时候,使用此功能可能会在重新分配中丢失数据。
此外,您的功能会泄漏内存。它malloc()
的空间几乎足以满足全局变量nowy
指向的字符串,然后使用函数参数new
覆盖指向该空间的唯一指针。
此外,您的功能无法发出信号失败的好方法。
这将是一个正确,更安全,无泄漏的实现:
/*
* Ensures that the dynamic array of char * pointed to by '*tabs' has
* sufficient capacity for exactly 'size' + 1 elements, and stores the
* value of 'el' at the last position. Updates *tabs with a pointer to
* the (possibly different) location of the enlarged array. Returns the
* location of the array, or NULL if memory allocation fails (in which
* case '*tabs' is unchanged, and still a valid pointer to allocated memory).
*/
char **addElem(char ***tabs, size_t size, char *el) {
char **newtabs = realloc(*tabs, (size + 1) * sizeof(char *));
if (newtabs) {
*tabs = newtabs;
(*tabs)[size] = el;
}
return newtabs;
}
答案 1 :(得分:0)
一个关于三重指针的非常简单的程序:
#include <stdio.h>
void printElem(int ***tabs) {
printf("%d\n",***tabs);
}
int main()
{
printf("Hello, World!\n");
int b = 7;
int *d;
int **t;
d = &b;
t = &d;
printElem(&t);
return 0;
}
output:
sh-4.3# main
Hello, World!
7