c - 在 C 中释放内存时出现段错误

标签 c pointers memory integer free

所以我正在运行该程序来克服整数溢出,并且在调试时它会运行第一个命令 hugePrint(p = parseString("12345"));没有问题。它在 hugeDestroyer(p) 之后运行代码;并毫无问题地释放内存。一旦我在 Ubuntu 中运行下一行代码,我就会遇到段错误,它甚至不会打印数字,但在 Windows 上它会打印“354913546879519843519843548943513179”,然后在运行 hugeDestroyer(p) 后给我一个段错误;再次。通过我的 parseString() 函数运行 NULL 值也有问题。非常感谢任何帮助阐明段错误。

// main
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "Fibonacci.h"

// print a HugeInteger (followed by a newline character)
void hugePrint(HugeInteger *p)
{
    int i;

    if (p == NULL || p->digits == NULL)
    {
        printf("(null pointer)\n");
        return;
    }

    for (i = p->length - 1; i >= 0; i--)
        printf("%d", p->digits[i]);
    printf("\n");
}

int main(void)
{
    HugeInteger *p;

    hugePrint(p = parseString("12345"));
    hugeDestroyer(p);

    hugePrint(p = parseString("354913546879519843519843548943513179"));
    hugeDestroyer(p);

    hugePrint(p = parseString(NULL));
    hugeDestroyer(p);

    hugePrint(p = parseInt(246810));
    hugeDestroyer(p);

    hugePrint(p = parseInt(0));
    hugeDestroyer(p);

    hugePrint(p = parseInt(INT_MAX));
    hugeDestroyer(p);

    hugePrint(p = parseInt(UINT_MAX));
    hugeDestroyer(p);

    return 0;
}

//fibonacci.c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "Fibonacci.h"


// Functional Prototypes
/*
HugeInteger *hugeAdd(HugeInteger *p, HugeInteger *q)
{

}
*/


HugeInteger *hugeDestroyer(HugeInteger *p)
{
    int i;
    if ( p == NULL )
        return NULL;

    if( p->length != NULL)
        free(p->length);

    if ( p->digits != NULL )
    {
        for ( i = 0; i < p->length; i++)
            free( p->digits[i] );
        free( p->digits );
    }
    free( p );

    return NULL;

}

HugeInteger *parseString(char *str)
{

    int counter, reverseCount = 0;
    HugeInteger *numArray = malloc(sizeof(HugeInteger));

    if ( str == NULL)
    {
        return NULL;
    }
//checks for NULL pointer
    if ( numArray == NULL)
    {
        return NULL;
    }

// Dynamically allocate memory for array of numbers
    numArray->length = strlen(str);
    numArray->digits = malloc( sizeof(int) * numArray->length+1);

    if ( numArray->digits == NULL)
        return NULL;

    for( counter = numArray->length - 1 ; counter >= 0 ; counter--)
    {
        numArray->digits[reverseCount] = str[counter];

// Handles conversion from ASCII to integer format
        switch(numArray->digits[reverseCount])
        {
        case 48:
            numArray->digits[reverseCount] = 0;
            break;
        case 49:
            numArray->digits[reverseCount] = 1;
            break;
        case 50:
            numArray->digits[reverseCount] = 2;
            break;
        case 51:
            numArray->digits[reverseCount] = 3;
            break;
        case 52:
            numArray->digits[reverseCount] = 4;
            break;
        case 53:
            numArray->digits[reverseCount] = 5;
            break;
        case 54:
            numArray->digits[reverseCount] = 6;
            break;
        case 55:
            numArray->digits[reverseCount] = 7;
            break;
        case 56:
            numArray->digits[reverseCount] = 8;
            break;
        case 57:
            numArray->digits[reverseCount] = 9;
            break;
        default:
            numArray->digits[reverseCount] = 0;
            break;
        }
        reverseCount++;
    }

    return numArray;

}

HugeInteger *parseInt(unsigned int n)
{
    HugeInteger *number = malloc(sizeof(HugeInteger));
    if( number == NULL )
        return NULL;

    if(n > UINT_MAX )
        return NULL;

    number = n;

    return number;

}
unsigned int *toUnsignedInt(HugeInteger *p)
{
    unsigned int *newInteger = malloc(sizeof(unsigned int));

    if( newInteger == NULL)
    {
        return NULL;
    }

    if (p == NULL || p > UINT_MAX )
    {
        return NULL;
    }

    newInteger = p;

    return newInteger;

}
/*
HugeInteger *fib(int n)
{
    // base cases: F(0) = 0, F(1) = 1
    if (n < 2)
        return n;
// definition of Fibonacci: F(n) = F(n – 1) + F(n - 2)
    return fib(n – 1) + fib(n – 2);
}
*/

//fibonacci.h
#ifndef __FIBONACCI_H
#define __FIBONACCI_H

typedef struct HugeInteger
{
    // a dynamically allocated array to hold the digits of a huge integer
    int *digits;

    // the number of digits in the huge integer (approx. equal to array length)
    int length;
} HugeInteger;


// Functional Prototypes

HugeInteger *hugeAdd(HugeInteger *p, HugeInteger *q);

HugeInteger *hugeDestroyer(HugeInteger *p);

HugeInteger *parseString(char *str);

HugeInteger *parseInt(unsigned int n);

unsigned int *toUnsignedInt(HugeInteger *p);

HugeInteger *fib(int n);


#endif

最佳答案

您的代码中存在多个问题。

当您malloc 获取 HugeInteger 时,您不会将返回的内存初始化为 0。因为当 str == NULL 时您在方法中提前返回,该结构的成员未初始化,因此当您对其调用 hugeDestroyer 时,您会得到未定义的行为,因为您不知道结构中的内存是什么样的。 p->digits 很可能不为空,它会尝试从中释放内存。


在 hugeDestroyer 中你有这段代码

if( p->length != NULL)
    free(p->length);

length 是一个 int 并且不是使用 malloc 动态分配的,因此调用 free 将把 int 解释为一个地址。又是未定义的行为。


同样在 hugeDestroyer 中,你有这段代码

for ( i = 0; i < p->length; i++)
    free( p->digits[i] );
free( p->digits );

这也是错误的,p->digits 以正确的大小分配了一次。您只需调用 free(p->digits) 因为 c 运行时会记住分配的大小。您的段错误再次由数字数组中的自由解释值作为要释放的内存地址引起。

关于c - 在 C 中释放内存时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22109439/

相关文章:

c - 循环运行无限次

c - 包含多个表和一个 malloc() 的数组

c - 选择和一些客户

c - 简单的指针算术题

c - 返回数组指针的函数的 C 语言语句是什么?

memory - 普通网卡有多少内存?

c - valgrind 报告未释放的 block

arrays - 戈朗 : unsafe dynamic byte array

mysql - 我应该使用 MEMORY (HEAP) 引擎还是 MyISAM 引擎创建 Mysql 表?

ruby - JSON的基于流的解析和写入