所以我有这段代码:
#include <stdio.h>
#include <stdlib.h>
void init_pointer_arr(void)
{
char *arr[1];
int command_count = 1;
int length_counter = 1;
int fixed_cols = 5;
int i, j;
// malloc -first- initialization of the array
*arr = malloc(sizeof(char) * 5);
if (arr == NULL) {
printf("17:malloc NULL");
}
/**************************************DEBUG***************************/
// init with char 'a' for debug purpose
for (i = 0; i < command_count; i++)
{
for (j = 0; j < length_counter*fixed_cols; j++)
{
arr[i][j] = 'a';
}
}
// print
for (i = 0; i < command_count; i++)
{
for (j = 0; j < length_counter*fixed_cols; j++)
{
printf("%c", arr[i][j]);
}
}
\*************************************END DEBUG*******************/
printf("\nrealloc\n"); // DEBUG
// realloc
//arr = realloc(arr, sizeof(arr[0]));
arr[0] = malloc(sizeof(char) * 5);
arr[1] = malloc(sizeof(char) * 5);
if (arr == NULL)
{
printf("51:malloc NULL");
}
/***************Re init newly allocate space for DEBUG*********************/
// init newly allocated space
for (i = 0; i < command_count; i++)
{
for (j = 0; j < length_counter*fixed_cols; j++)
{
arr[i][j] = 's';
}
}
printf("s\n"); // DEBUG
// print
for (i = 0; i < command_count; i++)
{
for (j = 0; j < length_counter*fixed_cols; j++)
{
printf("%c", arr[i][j]);
}
}
\******************************END DEBUG*****************************/
}
int main() {
init_pointer_arr();
system("pause");
return 0;
}
我基本上想要用指针数组实现一个二维数组,但我一直得到错误:&#34;内存arround arr已损坏&#34;这个错误的来源是这两行:
arr[0] = malloc(sizeof(char) * 5);
arr[1] = malloc(sizeof(char) * 5);
我已经看过其他关于此的帖子,但似乎没有人像我想的那样解决这个问题,而且上面的代码编译得很好,没有任何警告。
我很遗憾,为什么会这样。任何帮助将不胜感激。 提前谢谢。
编辑〜一开始arr只有一行,但在某些时候(上面麻烦的代码)我想添加更多行,我也试过realloc(你可以在另一个注释中看到它与另一行2以上)。但是那里也没有运气。
答案 0 :(得分:0)
<强>问题强>
- 将char *数组存储在不允许扩展的堆栈上
- 打印硬编码的行号(可能会改变)
- 没有退出失败(例如malloc失败)
- 内存泄漏(之后没有释放内存)
- system(&#34; pause&#34;)是特定于窗口的
调整后的代码
#include <stdio.h>
#include <stdlib.h>
void init_pointer_arr(void)
{
/* char *arr[1]; */
// store the char * s on the heap
char **arr, **temp;
int command_count = 1;
int length_counter = 1;
int fixed_cols = 5;
int i, j;
// malloc storage for the char * s
arr = malloc(command_count * sizeof(char *));
if(!arr)
{
goto err0;
}
// malloc -first-
arr[0] = malloc(sizeof(char) * 5);
if (arr[0] == NULL) {
// printf("17:malloc NULL");
printf("%d:malloc NULL\n", __LINE__);
// should return on failure :
goto err1;
}
// init
// you might want to put some \n in these printfs..
for (i = 0; i < command_count; i++)
{
for (j = 0; j < length_counter*fixed_cols; j++)
{
arr[i][j] = 'a';
}
}
// print
for (i = 0; i < command_count; i++)
{
for (j = 0; j < length_counter*fixed_cols; j++)
{
printf("%c", arr[i][j]);
}
}
printf("\nrealloc\n");
// realloc
command_count = 2;
temp = realloc(arr, command_count * sizeof(char *));
if(!temp)
{
goto err2;
}
arr = temp;
// arr[0] has already been alloced, not necessary again
// and will cause a leak
// arr[0] = malloc(sizeof(char) * 5);
arr[1] = malloc(sizeof(char) * 5);
if (arr[1] == NULL)
{
printf("%d:malloc NULL\n", __LINE__);
goto err2;
}
// init newly allocated space
for (i = 0; i < command_count; i++)
{
for (j = 0; j < length_counter*fixed_cols; j++)
{
arr[i][j] = 's';
}
}
printf("s\n");
// print
for (i = 0; i < command_count; i++)
{
for (j = 0; j < length_counter*fixed_cols; j++)
{
printf("%c", arr[i][j]);
}
}
err3:
free(arr[1]);
err2:
free(arr[0]);
err1:
free(arr);
err0:
return ;
}
int main() {
init_pointer_arr();
#if defined(_WIN32) || defined(WIN32)
system("pause");
#endif
return 0;
}
<强>输出强>
$ gcc -g test.c -o test
$ valgrind ./test
==3612== Memcheck, a memory error detector
==3612== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3612== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==3612== Command: ./test
==3612==
aaaaa
realloc
s
ssssssssss==3612==
==3612== HEAP SUMMARY:
==3612== in use at exit: 0 bytes in 0 blocks
==3612== total heap usage: 4 allocs, 4 frees, 34 bytes allocated
==3612==
==3612== All heap blocks were freed -- no leaks are possible
==3612==
==3612== For counts of detected and suppressed errors, rerun with: -v
==3612== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
<强>参考强>
答案 1 :(得分:0)
指甲的象征性的一点就是你宣称arr
是一个1 char *
(arr[0]
)的数组,但是你正在接近界限( arr[1]
)。
正如我之前在评论中提到的,错误数量的绝对数量表明您正在使用的资源不起作用。您应该考虑阅读并参加K&amp; R 2E的练习。它经过了试验和测试,通过成功教授成千上万的学生数十年来证明了这一点。
对于这个答案的其余部分,似乎可能有助于描述K&amp; R没有描述的相切的东西:在声明中利用VLA和优先级,向您展示为什么你的方向错误对这个。这应该证明为什么你应该花更多的时间磨斧子,所以说;在你削尖斧头之后,你的代码应该只有一行。那一行是:
char (*ptr_to_array)[y] = malloc(x * sizeof *ptr_to_array);
从技术上讲,你所描述的类型中有三个间接层:数组的两个维度(x和y轴,如果你愿意),一个维度是指向该类型的指针(z轴)。您可以使用typedef
:
typedef char two_dimensional_array[42][11];
two_dimensional_array *ptr; // ptr is a pointer to two_dimensional_array.
这对于VLA来说效果不好,所以您需要知道替代方案。让我们从简单的事情开始:
char *array[42];
应该很明显,这是一个指针数组,因为我告诉过你它是。你怎么读它作为一个数组?将标识符读为X,然后将标识符右侧的部分读为Y,然后将标识符左侧的部分读为Z,并形成以下句子:
X is Y of Z array is an array 42 of char *
现在考虑一些更复杂的事情:
char *array_of_array[42][11];
我会将此作为练习留给那些希望测试他们理解的人。下面的评论,我会告诉你,你是否正确。如果你做对了,请删除你的评论,这样你就不会破坏下一个人......
在下面的示例中,您应首先阅读括号,因为括号表示优先级。它是相同的模式,但是递归应用,首先读取括号内的内容。
char (*ptr)[42][11];
你的眼睛应该像往常一样被吸引到ptr
(建立X),并且在括号内的右手边没有任何东西,所以你的眼睛应该被吸引到{{1在括号内,表示它是一个指针。
然后你的眼睛应该按照我们之前建立的模式被吸引到括号外的右侧。那里有两个维数的阵列,它们从左到右阅读。因此指针(一维)指向具有两个维度的数组。
最后,你的眼睛应该被吸引到声明的最左边,以便在括号外读取该类型的其余部分。
我建议您在评论中描述您认为*
的类型。
假设您正确理解了所有这些内容,以下内容应该很容易破译,并且似乎符合您的要求:
ptr