【问题标题】:Segmentation fault, on the border ranges of int分段错误,在 int 的边界范围内
【发布时间】:2018-09-26 20:20:01
【问题描述】:

创建一个函数 ft_range,它返回一个整数数组。此 int 数组应包含最小值和最大值之间的所有值。 包含最小值 - 排除最大值。

#include <printf.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>

#include <stdlib.h>

int *ft_range(int min, int max)
{
    int *ptrInt;
    int i;
    int temp;
    temp = min;
    i = 0;
    ptrInt = NULL;
    if (max < min)
    {
        return (ptrInt);
    } else
    {
        ptrInt = malloc(max - min);
    }
    while (i < (max - min))
    {
        *(ptrInt + i) = temp + i;
        i++; /trows segfault at i == 473742332
    }
    return (ptrInt);
}



int *ft_range(int min, int max);

int main()
{
    int i = 0;
    int min = -947483640;
    int max =  947483640;
    int *ptr = ft_range(min, max);

    while (ptr != NULL)
    {
        printf("%d", *ptr);
        printf("%c", '\n');
    }
}

如果我输入更大的值,段错误也会抛出更大的值。 而且这段代码在较低的值上也能完美运行。

【问题讨论】:

  • ptrInt = malloc(max - min); **--&gt;&gt;** ptrInt = malloc((max - min) *sizeof *ptrInt); 此外,大多数人更喜欢数组表示法:*(ptrInt + i) = temp + i; -->> ptrInt[i] = temp + i;
  • 您遇到了段错误,因为您通过写入超出您malloced 的内存区域的大小来调用未定义的行为。 malloc 接受要分配的字节数。您机器上的sizeof int 肯定大于一个字节,因此仅分配max - min 字节不足以存储那么多ints。修复段错误后,您将在main 中进入无限循环。 ptr 永远不会在您的 while 循环中更新。
  • 如果这是两个独立的源文件,请注明。如果没有,通常所有的#include 指令都放在文件的顶部。
  • @wildplasser 谢谢你,它有帮助。
  • 还有一个极端情况 min==max ,没有被你的支票抓到,而是导致malloc(0)

标签: c malloc


【解决方案1】:

intchar 宽时,代码分配的内存不足——这很常见。

根据指向对象的大小进行分配。 @wildplasser

int *ptrInt;
...
  // ptrInt = malloc(max - min);
  ptrInt = malloc(sizeof *ptrInt * (max - min));
  //              ^------------^   ^---------^ number of elements
  //              +------------+-------------- size of 1 element

【讨论】:

  • 是否存在符合标准的 C 没有 intchar 更宽的情况?
  • @ChristianGibbons 已知一些图形处理器对所有整数类型使用相同的 64 位大小。不寻常,但 C 允许。
  • 很遗憾,我目前没有时间仔细研究标准,但不能保证 char 是一个字节(也就是说,该字节由 CHAR_BIT 定义或类似的),并且int 保证不少于两个字节?
  • 在 C 中,一个“字节”至少 8 位。研究CHAR_BITchar 使用 CHAR_BIT 位 - 一个 C“字节”。如果CHAR_BIT &gt;= 16 那么int 也可能是1 C“字节”。
  • 好吧,我暂时相信你的话。稍后我会在标准中查找它,但我相信这是准确的。
猜你喜欢
  • 1970-01-01
  • 2014-01-23
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 2012-06-12
  • 1970-01-01
  • 1970-01-01
  • 2022-06-20
相关资源
最近更新 更多