【问题标题】:Segmentation Fault when allocating memory to a pointer to pointer variable [C] [closed]将内存分配给指向指针变量的指针时出现分段错误 [C] [关闭]
【发布时间】:2018-08-08 06:48:18
【问题描述】:

我正在尝试使用指向指针的指针来表示字符串数组。所以我定义char** arr如下:

uint8_t lines = getLines();
char** arr = malloc (sizeof (char*) * lines);
// char** arr = malloc (sizeof (char*) * ROWS_COUNT);

在调试过程中,上面这行代码会成功执行并分配内存给arr。尝试分配足够的内存以在*(arr + 0) 中保存字符串时出现问题(以及错误),如下所示:

// #define PATH_MAX 4096
*arr = malloc (sizeof (char) * (PATH_MAX + 1));

运行时错误:

Signal: SIGSEGV (Segmentation fault)

注意:我使用了强制转换运算符(char** 的第一个赋值和char* 的第二个赋值)。它也不起作用。

注意:为了简单起见,我在这里使用了ROW_COUNTS。在原始代码中,我使用了一个lines 变量来代替ROWS_COUNT。 lines 包含一个 uint8_t 值。 (就我而言,3)

【问题讨论】:

  • 这看起来不错,你能发布更多代码吗?
  • 这两行不会导致段错误(除非ROWS_COUNT 或PATH_MAX 发生了一些奇怪的事情)。请发帖minimal reproducible example。
  • 就是这样;没有更多与该主题相关的行。为了简单起见,我在这里使用了 ROW_COUNT。实际上,我使用的是一个名为 lines 的变量;其中包含3 的值。 PATH_MAX(我认为是系统相关的)是一个常量,它定义了 Linux 系统上的最大路径长度。
  • 如果malloc 触发了段错误,您可能已经在此分配之前的“数百行”中使用其他代码破坏了堆(引用 you来自您在以下答案之一中的评论)。仅凭您在此处展示的内容,您所能期望的最好的就是 wags (wild-ass-guesses)。这个网站不是关于猜测的。这是关于答案。提供minimal reproducible example 否则这个问题可能是短暂的。
  • 顺便说一句,char (*arr)[PATH_MAX+1] = calloc(ROW_COUNT, sizeof *arr); 看起来很简单,如果你真的只是想获得ROW_COUNT 固定char 缓冲区空间的数量。除非您需要独立的字符串指针以供以后替换和释放,否则我会选择该替代方案;单分配;单人免费。

标签: c segmentation-fault malloc


【解决方案1】:

您可以在 single malloc() 中动态分配内存,试试这个代码:-

char (*arr)[ROWS_COUNT][PATH_MAX + 1] = malloc (sizeof(*arr));

您可以使用 strings 访问:-

(*arr)[ index ] 

和字符使用:-

(*arr)[ row ] [ column ]

示例:-

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PATH_MAX 4096
#define  ROWS_COUNT 500
int main()
{
    char (*arr)[ROWS_COUNT][PATH_MAX + 1] = malloc (sizeof(*arr));
    strcpy((*arr)[400],"Hello World");
    printf("\n String    : %s",(*arr)[400]);
    printf("\n Character : %c",(*arr)[400][2]);
}

输出:-

 String    : Hello World
 Character : l

【讨论】:

  • 对不起,我忘了注意我在这里使用ROWS_COUNT 为简单起见。在原始代码中,我使用了一个名为lines 的变量。 (添加到主帖中的注释)顺便说一句,如果有人使用常量名称作为行计数器,这似乎是一个很好的解决方案。
  • 请注意,这将需要对使用 arr 的代码的其余部分进行彻底更改(arr 必须是 (*arr)。OP,大多数 i>,需要一个数组数组。例如:char (*arr)[PATH_MAX+1] = calloc(ROW_COUNT, sizeof *arr);
  • @WhozCraig 对不起,我错过了* 操作员。我已经改成sizeof(*arr)。
  • @anoopknr 仍然没有必要将两个维度都下标以获得单个分配。
【解决方案2】:
// #define PATH_MAX 4096
*arr = malloc (sizeof (char) * (PATH_MAX + 1));

我认为这条线需要在ROWS_COUNT 次的循环内。这样就可以为所有要存储的行分配内存。

使用 Xcode(版本 9.3 (9E145))在 MAC 上测试,工作正常:

char** arr = (char**) malloc (sizeof (char*) * 1000);
int i = -1;
while(++i < 1000)
{
    *(arr + i) = (char*) malloc (sizeof (char) * (PATH_MAX + 1));
}

【讨论】:

  • 顺便说一句,在第一个循环(假设 i = 0)上,必须执行相同的语句。 (这会导致错误)
  • @noteworthy - 我在带有 xcode 的 MAC 上,刚刚测试了我在答案中添加的代码以保留格式。这段代码工作正常。我还注意到 PATH_MAX 在 syslimits.h 中定义为 1024。
  • i 在您的示例的循环主体中从 1 变为 1001,这是一个关闭 2 错误并且不会初始化第一个元素。
  • 你应该使用 for 循环而不是那个讨厌的 while 循环。 for(size_t i=0; i&lt;1000; i++) { arr[i] = malloc(...); } 这样您还可以删除您在当前代码中编写的错误:*(arr + 1000) = 写入超出数组范围。
  • “少击键”是以某种方式编写算法的可怕理由。编程就是敲击键盘上的一大堆键。如果那不是你的事,那么编程不适合你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-16
  • 2020-02-18
  • 1970-01-01
相关资源
最近更新 更多