C中结构的动态内存分配问题
Problems with dynamic memory allocation for structs in C
我得到了数量未知的 "wide symbols"。文本格式为句子,我必须将其添加到结构 "Text".
这些是我的结构:
struct Sentence {
wchar_t *sentence;
int amount_of_symbols;
};
struct Text {
struct Sentence *sentences;
int amount_of_sentences;
};
我为 "Sentence" 结构数组动态分配内存并添加它们。
这是我的输入代码:
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] = '[=11=]';
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 太小并且没有考虑终止 '[=14=]'
。在程序的顶部,执行:
int buffer_size = 1;
wchar_t *buffer = (wchar_t *) malloc(buffer_size * sizeof(wchar_t));
*buffer= '[=10=]';
但真正的问题在于:
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= '[=13=]';
问题就在这里
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 标准...
The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by 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));
其他一些注意事项...
As Paul noted,您需要为空字节分配一个额外的字节。
There's no need to cast the result of malloc
or realloc
.
在堆栈上分配一个大缓冲区来读取输入(如果需要,增加它)会更简单、更快且更不容易出错。然后将内容复制到适当大小的内存中。
I went ahead and coded up an improved version来说明。如果这是作业,请不要交。
我得到了数量未知的 "wide symbols"。文本格式为句子,我必须将其添加到结构 "Text".
这些是我的结构:
struct Sentence {
wchar_t *sentence;
int amount_of_symbols;
};
struct Text {
struct Sentence *sentences;
int amount_of_sentences;
};
我为 "Sentence" 结构数组动态分配内存并添加它们。 这是我的输入代码:
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] = '[=11=]';
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 太小并且没有考虑终止 '[=14=]'
。在程序的顶部,执行:
int buffer_size = 1;
wchar_t *buffer = (wchar_t *) malloc(buffer_size * sizeof(wchar_t));
*buffer= '[=10=]';
但真正的问题在于:
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= '[=13=]';
问题就在这里
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 标准...
The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by 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));
其他一些注意事项...
As Paul noted,您需要为空字节分配一个额外的字节。
There's no need to cast the result of malloc
or realloc
.
在堆栈上分配一个大缓冲区来读取输入(如果需要,增加它)会更简单、更快且更不容易出错。然后将内容复制到适当大小的内存中。
I went ahead and coded up an improved version来说明。如果这是作业,请不要交。