我正在创建一个程序,在学习C的学习阶段。给定的代码是我的代码的原型。我想做的是在添加新单词时动态地增加指针数组的长度。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 20
int main(){
char (*string)[0];
char word[MAX_LENGTH + 1];
string = malloc (sizeof(char));
if(string == NULL)
exit(EXIT_FAILURE);
for (int i = 0; i < 5; i++){
printf("Enter word: ");
scanf("%20s", word);
string = realloc (string, strlen(word) + sizeof(string));
if(string == NULL)
exit(EXIT_FAILURE);
strcpy(string[i], word);
printf("%s\n", string[i]);
}
for (int i = 0; i < 5; i++){
printf("%d: %s\n", i + 1, string[i]);
}
}
但是所发生的是相同的字存储在每一个字符串中。这是输出
Enter word: hello
hello
Enter word: this
this
Enter word: is
is
Enter word: the
the
Enter word: output
output
1: output
2: output
3: output
4: output
5: output
---NOT OUTPUT BUT WHAT I WAS EXPECTING---
Enter word: hello
hello
Enter word: this
this
Enter word: is
is
Enter word: the
the
Enter word: output
output
1: hello
2: this
3: is
4: the
5: output
我不知道我做错了什么。我在google上搜索了几个小时,堆栈溢出和reddit,没有找到任何我能联系到的东西。我做错了什么以及如何修复它。编译器没有给出任何错误,输出在vs代码中为空白。
发布于 2021-05-22 12:05:16
我想要做的是在添加新单词时动态地增加指针数组的长度。
您需要对每个单词(“realloc()
”)进行指针数组("string")和malloc()
数组。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 20
int main(){
char **string = NULL;
char word[MAX_LENGTH + 1];
for (int i = 0; i < 5; i++){
printf("Enter word: ");
scanf("%20s", word);
string = realloc(string, (i + 1) * sizeof(char *));
if (string == NULL)
exit(EXIT_FAILURE);
string[i] = malloc(strlen(word)+1);
if(string[i] == NULL)
exit(EXIT_FAILURE);
strcpy(string[i], word);
printf("%s\n", string[i]);
}
for (int i = 0; i < 5; i++){
printf("%d: %s\n", i + 1, string[i]);
}
}
但是,如果您知道要询问的单词数量,最好是简化缓冲区,而不是动态地分配和调整缓冲区大小。如果代码更好的话,代码会更简单,性能也会更好。
如果性能是一个考虑因素,并且单词数量未知,我建议重新分配每512个单词(假设最常见的64位/4kB块大小架构),并预先分配更大的内存块,以便自己拆分成单词,因为一直为每个单词调用malloc()
将是影响性能的主要因素。
您还应该考虑不同的、不那么容易混淆的变量名。对于指向指针的指针,string
不是一个很好的名称。
发布于 2021-05-22 12:38:01
我想要做的是在添加新单词时动态地增加指针数组的长度。
不,你不知道。如果你事先知道你想读的单词的数量,就没有必要一次又一次地重新分配指针数组。
虽然您现在可能不关心性能,但您应该记住,动态内存分配是一项非常昂贵的操作。
而且,您的名称选择是相当混乱的:string
建议使用单个字符串,而不是多个字符串。
所以,也许:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH 20
#define NUM_WORDS 5
int main(){
char* words[NUM_WORDS];
char word_scan_buffer[MAX_LENGTH + 1];
for (int i = 0; i < NUM_WORDS; i++){
printf("Enter word: ");
scanf("%20s", word_scan_buffer);
words[i] = malloc(strlen(word_scan_buffer)+1);
if (words[i] == NULL) {
fprintf(stderr, "Memory allocation for the %d'th string failed\n", i+1);
exit(EXIT_FAILURE);
}
strcpy(string[i], word_scan_buffer);
printf("%s\n", words[i]);
}
for (int i = 0; i < NUM_WORDS; i++){
printf("%d: %s\n", i + 1, words[i]);
}
}
这也避免了重复使用“魔术号”5,切换到一个定义的常量;并且通过打印错误消息而不是仅仅退出来更优雅地失败。
最后,它甚至对每个单词的malloc()
空间都没有多大用处,因为您可以只使用malloc((MAX_LENGTH+1)*NUM_WORDS)
一次,首先在分配的缓冲区中设置指向单词的指针。另见本常见问题:
这说明了这个选项。
https://stackoverflow.com/questions/67653509
复制相似问题