繁体   English   中英

在C中为结构动态分配内存的问题

[英]Problems with dynamic memory allocation for structs in C

我得到了数量未知的“宽符号”。 文本的格式设置为句子,我必须将其添加到结构“文本”中。

这些是我的结构:

struct Sentence {
    wchar_t *sentence;
    int amount_of_symbols;
};

struct Text {
    struct Sentence *sentences;
    int amount_of_sentences;
}; 

我为“句子”结构数组动态分配内存并添加它们。 这是我的输入代码:

int amount_of_sentences = 0;
struct Sentence *sentences = (struct Sentence *) malloc(amount_of_sentences * sizeof(struct Sentence));

struct Text text = {sentences, amount_of_sentences};

wchar_t symbol;
int buffer_size = 0;
wchar_t *buffer = (wchar_t *) malloc(buffer_size * sizeof(wchar_t));

bool sentence_begun = true;

while (true) {
    symbol = getwchar();

    if (symbol == '\n')
        break;

    if (sentence_begun && symbol == ' ') {
        sentence_begun = false;
        continue;
    }

    buffer = (wchar_t *) realloc(buffer, (++buffer_size) * sizeof(wchar_t));
    buffer[buffer_size - 1] = symbol;

    if (symbol == '.') {
        buffer[buffer_size] = '\0';

        text.amount_of_sentences++;
        text.sentences = (struct Sentence *) realloc(text.sentences, text.amount_of_sentences * sizeof(struct Sentence));
        text.sentences[text.amount_of_sentences - 1].amount_of_symbols = buffer_size;
        text.sentences[text.amount_of_sentences - 1].sentence = (wchar_t *) malloc(buffer_size * sizeof(wchar_t));
        text.sentences[text.amount_of_sentences - 1].sentence = buffer;

        buffer_size = 0;
        buffer = (wchar_t *) realloc(buffer, buffer_size * sizeof(wchar_t));
        sentence_begun = true;
    }
}

一切似乎都很好,但是当我尝试输出所有句子时,并没有全部显示出来,有些重复了。

这是我的输出代码:

for (int i = 0; i < text.amount_of_sentences; i++) {
    wprintf(L"%ls\n", text.sentences[i].sentence);
}

输入输出示例:

adjsand. asdad.a.a. aaaa. adsa.


a.

adsa.
adsa.

此代码可能有什么问题,我应该更改什么?

首先,您的缓冲区太小1,并且不考虑终止符'\\0' 在程序的顶部,执行以下操作:

int buffer_size = 1;
wchar_t *buffer = (wchar_t *) malloc(buffer_size * sizeof(wchar_t));
*buffer= '\0';

但是真正的问题在于:

    text.sentences[text.amount_of_sentences - 1].sentence =
                (wchar_t *) malloc(buffer_size * sizeof(wchar_t));
    text.sentences[text.amount_of_sentences - 1].sentence = buffer;

    buffer_size = 0;
    buffer = (wchar_t *) realloc(buffer, buffer_size * sizeof(wchar_t));

您为句子分配内存,但是随后用buffer指针覆盖了该指针。 接下来,您重置缓冲区大小并重新分配缓冲区。

分配复制缓冲区中的数据。 为此,请执行以下操作:

    strcpy(text.sentences[text.amount_of_sentences - 1].sentence, buffer);

在这里,也要做:

buffer_size = 1;
buffer = (wchar_t *) realloc(buffer, buffer_size * sizeof(wchar_t));
*buffer= '\0';

问题在这里。

    text.sentences[text.amount_of_sentences - 1].sentence = (wchar_t *) malloc(buffer_size * sizeof(wchar_t));
    text.sentences[text.amount_of_sentences - 1].sentence = buffer;

    buffer_size = 0;
    buffer = (wchar_t *) realloc(buffer, buffer_size * sizeof(wchar_t));

您可以使用malloc分配一个新语句,然后使用buffer覆盖它。 这将泄漏内存。

然后,将buffer分配给text.sentences[text.amount_of_sentences - 1].sentence ,然后通过重新分配buffer释放该内存。

从C标准...

realloc函数取消分配ptr指向的旧对象,并返回一个指向具有size指定大小的新对象的指针。

text.sentences[text.amount_of_sentences - 1].sentence指向已释放的内存。 这将导致不确定的行为。

而是指向buffer并分配一个新的buffer

    text.sentences[text.amount_of_sentences - 1].sentence = buffer;

    buffer_size = 0;
    buffer = malloc(buffer_size * sizeof(wchar_t));

其他注意事项...

如Paul所述 ,您需要为空字节分配一个额外的字节。

无需realloc mallocrealloc的结果

在堆栈上分配一个较大的缓冲区以读取输入(如果需要的话,增加它)是更简单,更快和更不容易出错的错误。 然后将内容复制到适当大小的内存中。

我继续编写了一个改进的版本进行说明。 如果这是家庭作业,请不要上交。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM