【问题标题】:Passing C char array and allocating causing program to crash传递 C char 数组并分配导致程序崩溃
【发布时间】:2012-08-14 19:06:57
【问题描述】:

我不知道错误是什么,因为这是在 Windows 上,我不知道如何在 Windows 上逐步执行程序。关于程序为什么在这里崩溃的任何想法(请参阅注释行)?我认为这可能与内存滥用有关。

#define TABLE_MAX_ROW       500
#define TABLE_MAX_COL       20
#define TABLE_MAX_ELT_LEN   60

从这里开始:

foo()
{
    char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN];

    bar(table);
}

传递给这个函数:

bar(char table[TABLE_MAX_ROW][TABLE_MAX_COL][TABLE_MAX_ELT_LEN])
{
    unsigned int col, row;

    if (table == NULL) { // crashes here
        printf("error: table == NULL!\n");
        return -1;
    }

    for (row = 0; row < TABLE_MAX_ROW; row++)
    for (col = 0; col < TABLE_MAX_COL; col++)
        table[row][col][0] = '\0'; // if above if block commented out, crashes here

    return 0;
}

【问题讨论】:

  • 这是一个相当大的数组,要在堆栈上分配。如果将“最大值”更改为 1 1 和 1 会发生什么?
  • 我无法在 Windows Visual C++ Express 中重现任何崩溃。
  • 在我的机器上运行良好,使用 MinGW 编译,包括 windows.h 和 iostream。
  • @ddyer 将值初始化为 1 1 1 使其不会崩溃。所以大分配是导致它崩溃的原因。有什么办法吗? (Windows 8)@Razvan 是的
  • IIRC Windows 中的标准堆栈大小约为 1 MB,而 Linux 为 8MB,因此可以说 ddyer 有所作为。

标签: c windows memory


【解决方案1】:

正如所写,bar 中的 NULL 检查是不必要的,因为table 不是在foo 中动态分配的。

话虽如此,您可能使用该数组定义 (60 Kb) 超出堆栈帧大小,这会导致 bar 出现运行时问题,从而导致崩溃。

尝试如下动态分配数组:

void foo (void) // explicitly type all functions
{
  /**
   * Declare a *pointer* to a 2D array of col x len and
   * allocate rows elements of it:
   */
  char (*table)[TABLE_MAX_COL][TABLE_ELT_LEN] =
    malloc(sizeof *table * TABLE_MAX_ROW);

  if (table)
  {
    bar(table);
  }

  free(table);
}

int bar(char (*table)[TABLE_MAX_COL][TABLE_ELT_LEN])
{
  unsigned int row, col;

  /**
   * Some duplication of effort here, since we made the null check
   * in foo, but what the heck.
   */
  if (!table)
  {
    // handle error as above
    return -1;
  }

  // process table as above
  return 0;
}

【讨论】:

    【解决方案2】:

    尝试为正在创建的 3D 数组分配空间

    char*** table = malloc(sizeof( sizeof( sizeof(char) * TABLE_MAX_ELT_LEN ) * TABLE_MAX_COL ) * TABLE_MAX_ROW)

    这至少会为您的所有元素提供足够的空间。

    【讨论】:

    • 谢谢,迈克。我不是你所说的精通 C 语言的人。你能告诉我如何将它整合到现有的工作流程中吗?我不想更改bar 参数。
    • 现在你的 bar 参数是一个 char 指针(一个字符数组 [C String])。据我所知,您必须更改 bar 函数的参数。您需要将其设为字符数组数组(字符串数组数组)或字符串矩阵。
    【解决方案3】:

    程序内存取决于操作系统。我强烈怀疑崩溃的原因是您的系统无法满足堆栈上如此大的数组分配(几乎 0.6MB!)。最好选择malloc

    【讨论】:

      【解决方案4】:

      问题可能是您的堆栈上没有足够的空间来分配这么大的缓冲区。我建议你dynamically allocate 数组。

      您还可以使用this 帖子中所述的便利宏分配一个您索引到的平面缓冲区。唯一的区别是你的数组是“3d”而不是“2d”。

      【讨论】:

        【解决方案5】:

        您正在使用堆栈上的 500x20x60=600000 字节为“table”变量分配。

        如果你的外壳是bash

        ulimit -slimit stacksize 代表 [t]csh)

        将显示您可以在程序堆栈上使用的最大内存量。 如果您使用超过此限制,这就是您的程序段错误的原因。

        【讨论】:

          猜你喜欢
          • 2023-03-17
          • 1970-01-01
          • 2015-11-03
          • 2012-01-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多