在 class 中访问 malloc 二维数组时出现段错误
Seg Fault upon accessing malloc'd 2d array in class
这是一个 class,其中包含一个名为 "map" 的二维字符数组。首先,我将 [mapDimension] char*s 分配给一个 char**。然后,我将 [mapDimension] 字符分配给每个 char*。我这样做而不是静态的:char map[mapDimension][mapDimension] 因为虽然这适用于小数字,但一旦 mapDimension 超过 2500 左右,它也会出现段错误。我想在堆上而不是堆栈上分配内存,这样我就可以容纳更多。
构造函数中的最后两行是将二维数组中的每个字符初始化为 0,然后将中心的一个设置为 5。
#define mapDimension 1000
class Field
{
private:
int i;
public:
char** map = (char**)malloc(mapDimension * sizeof(char*));
Field()
{
for(i = 0; i < mapDimension; i++)
map[i] = (char*)malloc(mapDimension * sizeof(char));
memset(map, 0, mapDimension*mapDimension*sizeof(char));
map[mapDimension/2][mapDimension/2] = 5;
}
};
int main()
{
Field field;
return 0;
}
这种动态方法也会出现段错误。我做错了什么?
memset(map, 0, mapDimension*mapDimension*sizeof(char));
您正在清除 map
数组( 指针数组 ),因此 map[x] 现在包含 NULL。您可能应该在循环中使用 map[i]
来清除分配的内存。
但是
- 当你分配内存时,你应该释放它(有 malloc,没有空闲可见)
- 在 C++ 中使用
new[]
和 delete[]
而不是 malloc
- 更好 - 使用
std::vector<std::vector<char>>
此声明无效
memset(map, 0, mapDimension*mapDimension*sizeof(char));
您分配了多个内存范围,而不是一个连续的存储区域。
你必须使用循环。例如
for ( i = 0; i < mapDimension; i++ ) memset( map[i], 0, mapDimension );
并且您的 class 必须有一个析构函数来释放分配的内存。
例如
~Field()
{
for( i = 0; i < mapDimension; i++ ) free( map[i] );
free( map );
}
最好让mapDimension
像一个size_t
类型的静态常量变量,而不是使用宏定义。
请注意,在 C++ 中您应该使用运算符 new
而不是 C 函数 malloc
。
您也可以简单地使用容器 std::vector<std::string>
而不是手动分配的数组。
首先,可以分配您的数组,这样您就可以一次性 memset
整个数组。但是为此你必须将二级内存分配为一个连续的内存块,然后在行之间分配它
Field()
{
char *data_memory = (char *) malloc(mapDimension * mapDimension * sizeof(char));
for (i = 0; i < mapDimension; i++)
map[i] = data_memory + i * mapDimension;
...
}
其次,如果您将分配方法更改为 "single block allocation"(如上所述),那么为了 memset
整个事情,您必须按如下方式进行
memset(map[0], 0, mapDimension * mapDimension * sizeof(char));
或
memset(&map[0][0], 0, mapDimension * mapDimension * sizeof(char));
注意memset
的第一个参数。
但是如果您坚持当前的分配方法,那么您就可以忘记在整个数组上使用 memset
。您的数组在内存中不连续。你不能 memset
整件事。您所能做的就是 memset
每行单独
for (i = 0; i < mapDimension; i++)
memset(map[i], 0, mapDimension * sizeof(char));
第三,将 i
声明为 class 的成员而不是使用局部变量 i
是个坏主意。此外,对第一个 malloc
使用 in-class 初始化程序也是一个坏主意。此外,在 C++ 中,您应该更喜欢使用 new/new[]
而不是 malloc
,甚至更不用说您应该更喜欢使用 std::vector
而不是手动数组内存管理。
这是一个 class,其中包含一个名为 "map" 的二维字符数组。首先,我将 [mapDimension] char*s 分配给一个 char**。然后,我将 [mapDimension] 字符分配给每个 char*。我这样做而不是静态的:char map[mapDimension][mapDimension] 因为虽然这适用于小数字,但一旦 mapDimension 超过 2500 左右,它也会出现段错误。我想在堆上而不是堆栈上分配内存,这样我就可以容纳更多。
构造函数中的最后两行是将二维数组中的每个字符初始化为 0,然后将中心的一个设置为 5。
#define mapDimension 1000
class Field
{
private:
int i;
public:
char** map = (char**)malloc(mapDimension * sizeof(char*));
Field()
{
for(i = 0; i < mapDimension; i++)
map[i] = (char*)malloc(mapDimension * sizeof(char));
memset(map, 0, mapDimension*mapDimension*sizeof(char));
map[mapDimension/2][mapDimension/2] = 5;
}
};
int main()
{
Field field;
return 0;
}
这种动态方法也会出现段错误。我做错了什么?
memset(map, 0, mapDimension*mapDimension*sizeof(char));
您正在清除 map
数组( 指针数组 ),因此 map[x] 现在包含 NULL。您可能应该在循环中使用 map[i]
来清除分配的内存。
但是
- 当你分配内存时,你应该释放它(有 malloc,没有空闲可见)
- 在 C++ 中使用
new[]
和delete[]
而不是malloc
- 更好 - 使用
std::vector<std::vector<char>>
此声明无效
memset(map, 0, mapDimension*mapDimension*sizeof(char));
您分配了多个内存范围,而不是一个连续的存储区域。
你必须使用循环。例如
for ( i = 0; i < mapDimension; i++ ) memset( map[i], 0, mapDimension );
并且您的 class 必须有一个析构函数来释放分配的内存。
例如
~Field()
{
for( i = 0; i < mapDimension; i++ ) free( map[i] );
free( map );
}
最好让mapDimension
像一个size_t
类型的静态常量变量,而不是使用宏定义。
请注意,在 C++ 中您应该使用运算符 new
而不是 C 函数 malloc
。
您也可以简单地使用容器 std::vector<std::string>
而不是手动分配的数组。
首先,可以分配您的数组,这样您就可以一次性
memset
整个数组。但是为此你必须将二级内存分配为一个连续的内存块,然后在行之间分配它Field() { char *data_memory = (char *) malloc(mapDimension * mapDimension * sizeof(char)); for (i = 0; i < mapDimension; i++) map[i] = data_memory + i * mapDimension; ... }
其次,如果您将分配方法更改为 "single block allocation"(如上所述),那么为了
memset
整个事情,您必须按如下方式进行memset(map[0], 0, mapDimension * mapDimension * sizeof(char));
或
memset(&map[0][0], 0, mapDimension * mapDimension * sizeof(char));
注意
memset
的第一个参数。但是如果您坚持当前的分配方法,那么您就可以忘记在整个数组上使用
memset
。您的数组在内存中不连续。你不能memset
整件事。您所能做的就是memset
每行单独for (i = 0; i < mapDimension; i++) memset(map[i], 0, mapDimension * sizeof(char));
第三,将
i
声明为 class 的成员而不是使用局部变量i
是个坏主意。此外,对第一个malloc
使用 in-class 初始化程序也是一个坏主意。此外,在 C++ 中,您应该更喜欢使用new/new[]
而不是malloc
,甚至更不用说您应该更喜欢使用std::vector
而不是手动数组内存管理。