【问题标题】:Memory leak (?) when converting from string to integer in C在 C 中从字符串转换为整数时的内存泄漏 (?)
【发布时间】:2015-06-12 15:05:27
【问题描述】:

所以我编写了这个程序,它从名为“input.txt”的文本文件中读取两行文本(它有两行,每行一个数字),然后将两个数字转换为两个不同数组中的整数。对于整数数组,我使用 malloc 和 realloc 来动态分配内存。正如您在下图中看到的,它适用于第二个数字,但第一个数字只是一些随机数(每次都会更改)。为什么会这样?

(我正在使用代码块。)

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define SIZE_MAX 10
#define SIZE_USE (SIZE_MAX-1)

int input(char num_first[], char num_second[]);
int convert(int iinum_first[], int iinum_second[], char num_first[], char num_second[], int firstlen, int secondlen, int c, int c2);

int main()
{

    char num_first[SIZE_MAX]; // original input as string
    char num_second[SIZE_MAX];

    input(num_first, num_second);

    int firstlen = strlen(num_first)-1;
    int secondlen = strlen(num_second);

    int i, c=0, c2=0;
    for (i = 0; i <= firstlen; i++)
    {
        c++; // counts number of elements needed to resize array
    }
    for (i = 0; i <= secondlen; i++)
    {
        c2++;
    }

    int *iinum_first = NULL; // converted integer input
    int *iinum_second = NULL;

    iinum_first = (int*)malloc(sizeof(int));
    iinum_second = (int*)malloc(sizeof(int));


    convert(iinum_first, iinum_second, num_first, num_second, firstlen, secondlen, c, c2);

    printf("first integer: ");
    for (i = 0; i < firstlen; i++) // print first integer
    {
        printf("%d", iinum_first[i]);
    }
    printf("\nsecond integer: ");
    for (i = 0; i < secondlen; i++) // print second integer
    {
        printf("%d", iinum_second[i]);
    }
    puts("");

    return 0;
}

int input(char num_first[], char num_second[])
{
    FILE *fPTR;
    int i;

    if ((fPTR = fopen("input.txt", "r")) == NULL)
    {
        puts(":( File could not be opened.");
    }
    else
    {
        if (fgets(num_first, SIZE_MAX, fPTR) != NULL)
            printf("first string: "); // print string input
        puts(num_first);
        if (fgets(num_second, SIZE_MAX, fPTR) != NULL)
            printf("second string: ");
        puts(num_second);
        fclose(fPTR);
    }

    return 0;
}

int convert(int iinum_first[], int iinum_second[], char num_first[], char num_second[], int firstlen, int secondlen, int c, int c2)
{
    // dynamic memory allocation

    int i;

    int *temp = NULL;
    int *temp2 = NULL;

    temp = (int*)realloc(iinum_first, c * sizeof(int));
    if (temp != NULL)
    {
        iinum_first = temp; // moving temporary data to main array
    }
    else
    {
        free(iinum_first);
        printf("Error allocating memory!\n");
        return 1;
    }


    temp2 = (int*)realloc(iinum_second, c2 * sizeof(int));
    if (temp2 != NULL)
    {
        iinum_second = temp2; // moving temporary data to main array
    }
    else
    {
        free(iinum_second);
        printf("Error allocating memory!\n");
        return 1;
    }

    for (i = 0; num_first[i] != '\0'; i++)
    {
        switch (num_first[i])
        {
        case 48:
            iinum_first[i] = 0;
            break;
        case 49:
            iinum_first[i] = 1;
            break;
        case 50:
            iinum_first[i] = 2;
            break;
        case 51:
            iinum_first[i] = 3;
            break;
        case 52:
            iinum_first[i] = 4;
            break;
        case 53:
            iinum_first[i] = 5;
            break;
        case 54:
            iinum_first[i] = 6;
            break;
        case 55:
            iinum_first[i] = 7;
            break;
        case 56:
            iinum_first[i] = 8;
            break;
        case 57:
            iinum_first[i] = 9;
            break;
        }
    }

    for (i = 0; num_second[i] != '\0'; i++)
    {
        switch (num_second[i])
        {
        case 48:
            iinum_second[i] = 0;
            break;
        case 49:
            iinum_second[i] = 1;
            break;
        case 50:
            iinum_second[i] = 2;
            break;
        case 51:
            iinum_second[i] = 3;
            break;
        case 52:
            iinum_second[i] = 4;
            break;
        case 53:
            iinum_second[i] = 5;
            break;
        case 54:
            iinum_second[i] = 6;
            break;
        case 55:
            iinum_second[i] = 7;
            break;
        case 56:
            iinum_second[i] = 8;
            break;
        case 57:
            iinum_second[i] = 9;
            break;
        }
    }

    return 0;
}

【问题讨论】:

  • 哦,天哪..这些开关要了我的命。为什么不只是iinum_first[i] = num_first[i] - 48 ??
  • @Eugene Sh.好点子。
  • 顺便说一句 SIZE_MAX 已被 C 使用。
  • @BLUEPIXY。但到目前为止一切正常。
  • @vvvsg 它最终会停止这样做,如果扩展了一些想要使用原始SIZE_MAX...

标签: c memory-leaks malloc realloc


【解决方案1】:

我修好了。在调用转换函数之前,我必须在 main 中使用 realloc。

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define SIZE_MAX 10
#define SIZE_USE (SIZE_MAX-1)

int input(char num_first[], char num_second[]);
int convert(int iinum_first[], int iinum_second[], char num_first[], char num_second[], int firstlen, int secondlen, int c, int c2);

int main()
{

    char num_first[SIZE_MAX]; // original input as string
    char num_second[SIZE_MAX];

    input(num_first, num_second);

    int firstlen = strlen(num_first)-1;
    int secondlen = strlen(num_second);

    int i, c=0, c2=0;
    for (i = 0; i <= firstlen; i++)
    {
        c++; // counts number of elements needed to resize array
    }
    for (i = 0; i <= secondlen; i++)
    {
        c2++;
    }

    int *iinum_first = NULL; // converted integer input
    int *iinum_second = NULL;

    iinum_first = (int*)malloc(sizeof(int));
    iinum_second = (int*)malloc(sizeof(int));

    int *temp = NULL;
    int *temp2 = NULL;

    temp = (int*)realloc(iinum_first, c * sizeof(int));
    if (temp != NULL)
    {
        iinum_first = temp; // moving temporary data to main array
    }
    else
    {
        free(iinum_first);
        printf("Error allocating memory!\n");
        return 1;
    }


    temp2 = (int*)realloc(iinum_second, c2 * sizeof(int));
    if (temp2 != NULL)
    {
        iinum_second = temp2; // moving temporary data to main array
    }
    else
    {
        free(iinum_second);
        printf("Error allocating memory!\n");
        return 1;
    }

    convert(iinum_first, iinum_second, num_first, num_second, firstlen, secondlen, c, c2);

    printf("first integer: ");
    for (i = 0; i < firstlen; i++) // print first integer
    {
        printf("%d", iinum_first[i]);
    }
    printf("\nsecond integer: ");
    for (i = 0; i < secondlen; i++) // print second integer
    {
        printf("%d", iinum_second[i]);
    }
    puts("");

    return 0;
}

int input(char num_first[], char num_second[])
{
    FILE *fPTR;
    int i;

    if ((fPTR = fopen("input.txt", "r")) == NULL)
    {
        puts(":( File could not be opened.");
    }
    else
    {
        if (fgets(num_first, SIZE_MAX, fPTR) != NULL)
            printf("first string: "); // print string input
        puts(num_first);
        if (fgets(num_second, SIZE_MAX, fPTR) != NULL)
            printf("second string: ");
        puts(num_second);
        fclose(fPTR);
    }

    return 0;
}

int convert(int iinum_first[], int iinum_second[], char num_first[], char num_second[], int firstlen, int secondlen, int c, int c2)
{
    // dynamic memory allocation
    int i;

    for (i = 0; num_first[i] != '\0'; i++)
    {
        switch (num_first[i])
        {
        case 48:
            iinum_first[i] = 0;
            break;
        case 49:
            iinum_first[i] = 1;
            break;
        case 50:
            iinum_first[i] = 2;
            break;
        case 51:
            iinum_first[i] = 3;
            break;
        case 52:
            iinum_first[i] = 4;
            break;
        case 53:
            iinum_first[i] = 5;
            break;
        case 54:
            iinum_first[i] = 6;
            break;
        case 55:
            iinum_first[i] = 7;
            break;
        case 56:
            iinum_first[i] = 8;
            break;
        case 57:
            iinum_first[i] = 9;
            break;
        }
    }

    for (i = 0; num_second[i] != '\0'; i++)
    {
        switch (num_second[i])
        {
        case 48:
            iinum_second[i] = 0;
            break;
        case 49:
            iinum_second[i] = 1;
            break;
        case 50:
            iinum_second[i] = 2;
            break;
        case 51:
            iinum_second[i] = 3;
            break;
        case 52:
            iinum_second[i] = 4;
            break;
        case 53:
            iinum_second[i] = 5;
            break;
        case 54:
            iinum_second[i] = 6;
            break;
        case 55:
            iinum_second[i] = 7;
            break;
        case 56:
            iinum_second[i] = 8;
            break;
        case 57:
            iinum_second[i] = 9;
            break;
        }
    }

    return 0;
}

【讨论】:

    【解决方案2】:

    你可以使用 atoi 来简化程序,而不是创建一个新的 weel,但我看到了唯一的区别

    int firstlen = strlen(num_first)-1; 而不是

    int firstlen = strlen(num_first);

    【讨论】:

    • btw 据我所知,atoi 返回一个整数,但我想要数组元素中的每个数字。
    • 好的,我更喜欢循环,比如int a = atoi(str); int n = log10(a)+1; int array[n]; for(i=1;i&lt;=n;i++) { array[n-i]=a%10; a /=10; }
    猜你喜欢
    • 1970-01-01
    • 2011-05-04
    • 2017-06-19
    • 2014-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    相关资源
    最近更新 更多