【问题标题】:How to use realloc with double char pointer in C?如何在C中使用带有双字符指针的realloc?
【发布时间】:2017-04-07 05:35:56
【问题描述】:

我试图在双字符指针中将内存增加一行,但由于某种原因程序崩溃了,即使我没有收到任何警告。我用谷歌搜索过,人们一直在提供这种方式来重新分配,但它对我不起作用。你知道问题在哪里吗?它在最后一行。

提前致谢!

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define E 255

void Palindromas(char* Zodis, char eilute[E], int *kiekis, char** Ats);

int main()
{
    char Eilute [E];
    int i, kiekis = -1;
    char** Ats;
    char* Zodis;

    Zodis = malloc(E * sizeof(char));
    Ats = malloc(1 * sizeof(char*));

    // Failu aprasymas

    FILE *Duomenys = fopen("Duomenys.txt", "r");
    FILE *Rezultatai = fopen("Rezultatai.txt","w");

    //--------------------------------

    if (Ats == NULL)
    {
        printf("Atmintis nebuvo paskirta");
        exit(0);
    }

    if (Zodis == NULL)
    {
        printf("Atmintis nebuvo paskirta");
        exit(0);
    }

    if (Duomenys == NULL) printf("Nurodyto duomenu failo nera \n");

    while(fgets(Eilute, sizeof(Eilute), Duomenys))
    {
        Palindromas(Zodis, Eilute, &kiekis, Ats);
    }

    for (i = 0; i <= kiekis; i++)
    {
        fprintf(Rezultatai, "%s ", Ats[i]);
    }

    free(Ats);
    free(Zodis);
    fclose(Duomenys);
    fclose(Rezultatai);

    return 0;
}

void Palindromas(char* Zodis, char Eilute[E], int *kiekis, char** Ats)
{
    int i, l, j, index, ilgis, eil;

    for(i = 0; 1 == sscanf(Eilute + i, "%s%n", Zodis, &l); i = i + l)
    {

        *kiekis = *kiekis + 1;
        index = 1;
        ilgis = strlen(Zodis);

        Ats[*kiekis] = malloc(ilgis * sizeof(char));

        for (j = 0; j < ilgis; j++)
        {
            if (Zodis[j] != Zodis[ilgis - j - 1])
                index = 0;
        }

        if (index == 1) strcpy(Ats[*kiekis], Zodis);

        eil = *kiekis + 2;
        Ats = realloc(Ats, eil * sizeof(char*));
    }
}

【问题讨论】:

  • 在你做任何其他事情之前,你应该搜索emulating pass by reference in C。当您分配给Palindromas 函数时,您认为Ats 会发生什么?这将如何影响main 函数中的Ats 变量?想想你在用kiekis做什么。
  • 此外,您正在写信给Ats[*kiekis],这在循环的第一次迭代中超出范围
  • 最后,不要重新分配回您传递给realloc 的指针变量。如果 realloc 失败,它将返回 NULL 并且您会丢失指针。并且总是检查错误(例如mallocrealloc 返回NULL)。
  • 没有最后一行 realloc 程序会打印出我需要的内容...我只是从动态内存开始,所以我还是个新手...
  • 这就是为什么你总是用英文写标识符的原因:你可能在某个时候让其他人阅读代码。如果您不使用英语,那么您几乎是靠自己的。

标签: c pointers dynamic char realloc


【解决方案1】:

我不得不用谷歌来理解你的代码,也许下次你可以帮我们翻译一下。

我有几点意见:

  • if (Duomenys == NULL) 只是打印一条错误消息,但不会停止执行。它应该像之前的验证一样(如果返回错误代码更好)。
  • Ats[*kiekis] = malloc(ilgis * sizeof(char)); 是错误的,应该是 Ats[*kiekis] = malloc((ilgis+1) * sizeof(char)); 因为它需要空结尾字符的空间。
  • if (Zodis[j] != Zodis[ilgis - j - 1]) index = 0; 很好,但if (Zodis[j] != Zodis[ilgis - j - 1]) { index = 0; break; } 更好,因为这样循环将在第一个不同的字符处停止。
  • if (index == 1) strcpy(Ats[*kiekis], Zodis); 必须是 if (index == 1) strcpy(Ats[*kiekis], Zodis);else --*kiekis 否则您的 Ats 数组也将不包含回文词。
  • 别忘了释放Ats 数组中的每个元素,然后再使用for(i=0; i&lt;=kiekis; i++) free(Ats[i]); 之类的东西释放数组本身

最后,回答您的问题,重新分配 Ats 数组即可:

Ats = realloc(Ats, (*kiekis+1) * sizeof(char*));

我会像这样重新组织你的功能:

void Palindromas(char* Zodis, char Eilute[E], int *kiekis, char** Ats)
{
    int i, l, j, index, ilgis;
    for(i = 0; 1 == sscanf(Eilute + i, "%s%n", Zodis, &l); i = i + l)
    {
        index = 1;
        ilgis = strlen(Zodis);
        for (j = 0; j < ilgis; j++)
        {
            if (Zodis[j] != Zodis[ilgis - j - 1])
            {
                index = 0;
                break;
            }
        }
        if (index == 1)
        {
            ++*kiekis;
            Ats = (char **)realloc(Ats, (*kiekis+1) * sizeof(char*));
            Ats[*kiekis] = dup(Zodis); // dup == malloc+strcopy
        } 
    }
}

【讨论】:

  • 感谢您的帮助和建议!对此,我真的非常感激。 :) 从我发布主要问题的那一刻起,我已经修复了你的所有观察结果,但是,在重新分配内存时,程序仍然崩溃......我已经用谷歌搜索了与你一样使用它的完全相同的方式重新说,但是程序在启动时会崩溃。 :( 我会尝试使用它,也许我会成功。 Ats = realloc(Ats, (kiekis+1) * sizeof(char));
  • 这是Ats = realloc(Ats, (*kiekis+1) * sizeof(char)); *kiekis+1 而不是kiekis+1
猜你喜欢
  • 1970-01-01
  • 2020-04-08
  • 2021-08-04
  • 2019-05-06
  • 1970-01-01
  • 2016-11-03
  • 2022-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多