指针指向指针的单个malloc调用;数组";导致无效写入
我在这里试图做的(出于教育目的)是让指针指向一个行为类似于数组但只有一个内存分配的指针。Valgrind正在抱怨这段代码,如果我使用多个分配执行更长版本的代码,我在gdb中调试时就会出现segfaults 它分配144字节(3个指针24字节,整数3*40字节)。l[0]是l的+24字节,l[1]是l[0]的+40字节,依此类推 有人能告诉我我做错了什么吗 gcc-o程序-g-ansi-Wpedantic-Wall-Wextra main.c指针指向指针的单个malloc调用;数组";导致无效写入,c,arrays,pointers,C,Arrays,Pointers,我在这里试图做的(出于教育目的)是让指针指向一个行为类似于数组但只有一个内存分配的指针。Valgrind正在抱怨这段代码,如果我使用多个分配执行更长版本的代码,我在gdb中调试时就会出现segfaults 它分配144字节(3个指针24字节,整数3*40字节)。l[0]是l的+24字节,l[1]是l[0]的+40字节,依此类推 有人能告诉我我做错了什么吗 gcc-o程序-g-ansi-Wpedantic-Wall-Wextra main.c #include <stdlib.h> #
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int **l;
int i, j, k;
int x = 3;
int y = 10;
size_t size_y = sizeof(int) * y;
size_t x_ptrs = x * sizeof(int*);
size_t mem_to_alloc = x_ptrs + x * size_y;
l = malloc(mem_to_alloc);
l[0] = (int*)l + x_ptrs;
l[1] = (int*)l + x_ptrs + size_y;
l[2] = (int*)l + x_ptrs + size_y * 2;
k = 0;
for(i = 0; i < x; i++)
for(j = 0; j < y; j++)
l[i][j] = (-k++)*12; /* just some number */
for(i = 0; i < x; i++) {
for(j = 0; j < y; j++) {
printf("%.3d\n", l[i][j]);
}
puts("");
}
free(l);
l = NULL;
return 0;
}
当您添加一个整数和一个指针时,该整数将按指针指向的大小放大。所以
l[1] = (int*)l + x_ptrs + size_y;
将l[1]
设置为40*sizeof(int)
过去的l
字节,即160
过去的l
。由于只分配了144
字节,因此超出了数组边界
这种自动缩放允许您使用指针算法逐步遍历数组,例如
ptr++
,以到达ptr
指向的数组的下一个元素。错误可能与此有关
当你在做l[0]=(int*)l+x_ptrs
,偏移量x_ptrs
是一个字节数。相反,它应该是您要跳过的整数数,因为l
被强制转换为int*
你能试试l[0]=(int*)l+2*x代码>?如果int*
(最有可能为8)的大小是int
(最有可能为4)大小的两倍,则应该可以使用。同样的逻辑也适用于size\u y
l[0] = (int*)l + 2*x;
l[1] = (int*)l + 2*x + y;
l[2] = (int*)l + 2*x + 2*y;
您应该从使用正确的变量名开始。像l[i][j]
这样的语句实际上是不可读的。l[0]是l的+24字节->这个语句是错误的l
与l[0]
@ex0ns有相同的地址。他说的是分配给l[0]
的内容,而不是它的地址。首先,它不会像你所期望的那样工作。其次,为什么不使用一个简单的指针,然后使用简单的数学来获得正确的索引?例如,int*matrix=malloc(xsize*ysize*sizeof(int));矩阵[x*ysize+y]=5代码>不要!可以使用2D数组,也可以将数组分为两部分:指针数组和其余部分。一个问题是您可能会遇到对齐问题。
l[0] = (int*)l + 2*x;
l[1] = (int*)l + 2*x + y;
l[2] = (int*)l + 2*x + 2*y;