【问题标题】:struct array length error结构数组长度错误
【发布时间】:2017-04-12 08:55:45
【问题描述】:

我是 C 的初学者,经过长时间的努力,我完成了我的 1500 行 C 代码。它运行完美并产生了预期的结果,但是当我尝试添加比测试更多的输入时,我遇到了故障.

更具体地说,我设法在结构数组中找到了问题的根源。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

#define ROWS 5000
#define MAXLOGGERS 26

struct data
    {
        int day;
        int month;
        int year;
        int hour;
        int minute;
        int second;
        float value;
        float temp;
        float hum;
    };  

int main()
{
    printf("Enter the number of loggers that you want to import: ");
    int n = 10;

    while (n > MAXLOGGERS)
    {
        printf("You can input data from maximum %d loggers: ", MAXLOGGERS);
        scanf("%d", &n);
    }

    struct data mydata[n+1][ROWS];

    printf("\n\nSuccess!!\n");
}

现在,当我使用 n = 10 或更少时,程序按预期完成。当我将 n 更改为 11 或更多时,它会崩溃。

我怀疑结构数组的声明有问题,但我真的想不通。

我们非常欢迎任何帮助! 谢谢(:

【问题讨论】:

  • after long time and effort I finished my 1500 rows code in C....好吧,再想想你的学习方法。
  • while (n &gt; MAXLOGGERS) 对任何 n &lt; 26 都是错误的,那么您如何准确输入输入?
  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码.没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建minimal reproducible example
  • 检查你的最大堆大小值
  • 您是否看到您分配 5000 * (n + 1 ) * ( sizeof(int) * 6 + 3 * sizeof(float)) 大约为:5000 * 12 * ( 2 * 6 + 3 * 4 ) = 1 440 000 字节。 [估计的 int 和 float 的大小,可能因每个系统而异]。检查您可以分配的最大大小;)

标签: c arrays struct


【解决方案1】:
struct data mydata[n+1][ROWS];

您正在堆栈上分配一个非常大的(二维)数组,该数组完全被 n &gt;= 11 消耗(在我的系统上也是如此,导致堆栈溢出,显示为分段错误)。

对于如此大的数据,您应该在堆上分配内存。这很好用(至少在我的机器上):

//struct data mydata[n+1][ROWS];
struct data* mydata = (struct data*)malloc(sizeof(struct data) * (n+1) * ROWS);
printf("\n\nSuccess!!\n");
free(mydata);

只是,对数组的访问不再那么好,因为您不能使用双索引运算符。您必须自己计算偏移量:

// mydata[x][y]; gets: 
mydata[x*ROWS + y];

不要监督对free 的调用 - 每个数据malloced 都应该是freed。从一开始就习惯这个原则(在输入malloc 的同时想到free)将有助于防止内存泄漏。

正如 cmets 中所暗示的(以及引用的答案),堆栈大小通常是有限的,而对堆施加的唯一限制是您机器的(但未使用的)物理内存的大小,这(通常)很远较大。如果您碰巧用完了系统内存,malloc 不会崩溃,而是返回一个空指针。所以你实际上应该检查:

struct data* mydata = (struct data*)malloc(sizeof(struct data) * (n+1) * ROWS);
if(mydata)
{
    printf("\n\nSuccess!!\n");
    free(mydata);
}
else
{
    printf("\n\nOut of memory!!\n");
}

【讨论】:

  • 你应该避免转换 malloc stackoverflow.com/questions/605845/… 的返回值。正如你所做的那样,始终释放已分配的内存 [我们这里不做 Java]
  • @kaldoran 好吧,关于是否进行演员阵容有不同的意见(显示 216 人赞成回答“为什么要这样做”......)。我个人(承认,来自 C++)坚持“做演员”部分的观点(再次承认:少数......)。
  • 确实如此,那么用户将选择是否这样做^^
  • 谢谢,这很好用!不幸的是,即使我将所有 mydata[x][y] 更改为 mydata[x*(n+1) + y];我得到的结果与以前不同,来自一个 x 的数据被另一个覆盖。这是有道理的,因为在我使用 mydata[x][y].hour/minute/second 校准记录器之前,它们都从同一时间开始,因此我需要更改大部分代码以竞争缺乏2x 矩阵。知道是否有一种方法可以增加堆栈容量,所以我不需要再次运行它?
  • x*(n+1) 只是为了说明 - 相反,我会先增加 n 并进一步使用增加的值:++n; malloc([...] * n * [...]); array[x*n+y]; - 如果你需要两者 (n, n+1),你可以使用第二个变量。与[x][y] 相比,您应该没有什么不同,实际上,后者无论如何都被编译器转换为前者...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 2023-03-04
  • 1970-01-01
  • 2014-11-14
  • 1970-01-01
相关资源
最近更新 更多