在使用malloc的数组中出现SIGSEGV错误

SIGSEGV error in array using malloc

本文关键字:SIGSEGV 错误 数组 malloc      更新时间:2023-10-16

我在这个代码中得到SIGSEGV错误,我无法弄清楚它。所以请有人帮帮我吧。我无法理解,如果我通过malloc函数分配内存到一个数组,我必须从0索引或1开始。

#include<iostream>
#include<stdio.h>
using namespace std;
#include<malloc.h>
long long int gold_coins(long long int[],long long int);
int main()
{
    long long int n,i,d;
    long long int* m;
    cin>>n;
    while(n!=EOF)
    {
        m = (long long int*) malloc(n+1);
        for(i=0;i<=n;i++)
           m[i]=i;
        d=gold_coins(m,n);
        cout<<d<<endl;
        cin>>n;
    }
    return(0);
}
long long int gold_coins(long long int m[],long long int n)
{
    if(n<4)
        return m[n];
    else
    {
        long long int q=gold_coins(m,n/2)+gold_coins(m,n/3)+gold_coins(m,n/4);
        if(q>m[n])
            m[n]=q;
        return(m[n]);
    }
}

我在这个代码中得到SIGSEGV错误,我无法弄清楚它。

让我们先解释一下什么是分段故障。

段错误

访问冲突是当进程试图访问无效的内存地址时产生的一个陷阱(系统异常/故障):要么它试图写只读内存,要么进程根本不被允许对该内存进行寻址,包括解引用空指针和寻址不存在的内存地址(这可以使用例如mmap进行操作)。在这种情况下,SIGSEGV信号(11)被发送给违规进程。

在硬件层面,分段故障是作为内存保护功能的一部分由内存管理单元提出的动作实现的。这个计算机硬件单元可以是一个单独的集成电路,也可以和中央处理器放在同一个集成电路上,如现代计算机中的微处理器。

要在程序代码中找到导致SIGSEGV的行,我们应该查看堆栈跟踪/堆栈窗口等。我们还可以在引起这种情况的行之前放置一个断点,并调查程序状态。如果堆芯已经被倾倒,我们也可以看看这个。Linux有一个grsecurity补丁集,可以增加对web服务器的缓冲区溢出、堆栈溢出等的保护。


malloc

标准函数malloc(),在我的实现中被声明为

/* Allocate SIZE bytes of memory.  */
extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur;

以要分配的字节数作为参数。

C标准§ 7.20.3.3 malloc函数

简介1

include

void *malloc(size_t size);

描述

2 malloc函数为指定大小的对象分配空间

返回

3 malloc函数返回空指针或指向已分配的空间。


这意味着这里

m = (long long int*) malloc(n+1);

你分配了n+1个字节,但是你需要(n+1)*sizeof(long long int)字节来存储long long int类型的n+1变量,因此你应该写:

m = malloc( ( n + 1) * sizeof( long long int));

或更好

m = malloc( ( n + 1) * sizeof *m)
   ^
   // in C cast should be omitted ( it is still needed if you want your code
   // to compile with a C++ compiler)
   // sizeof *m can be used as () are needed only for a type names
https://stackoverflow.com/a/605858/1141471