c – 为什么全局变量在不同方法中表现不同?
目标:
>创建字符串(字典)的全局数组,只要在函数load()中可以计算大小. 我的方法: 创建指向string的全局指针,在load()中创建字符串数组,并将本地数组分配给全局指针. 问题: 如果我尝试在load()中打印全局数组(以及本地数据),一切都很好,但是如果使用print()进行打印,则会在数组末尾的某处发生段错误. GDB和valgrind输出对我来说似乎很神秘.我放弃.怎么了? 来源和字典是here. 码: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> // length of the longest word in dictionary #define LENGTH 45 // dictionary file #define DICTIONARY "large" // prototypes void load(const char* dictionary); void print(void); // global dictionary size int dict_size = 0; // global dictionary char **global_dict; int main(void) { load(DICTIONARY); print(); return 0; } /** * Loads dictionary into memory. */ void load(const char* dictionary) { // open dictionary file FILE *dict_file = fopen(dictionary,"r"); // compute size of dictionary for (int c = fgetc(dict_file); c != EOF; c = fgetc(dict_file)) { // look for 'n' (one 'n' means one word) if (c == 'n') { dict_size++; } } // return to beginning of file fseek(dict_file,SEEK_SET); // local array char *dict[dict_size]; // variables for reading int word_length = 0; int dict_index = 0; char word[LENGTH + 1]; // iteration over characters for (int c = fgetc(dict_file); c != EOF; c = fgetc(dict_file)) { // allow only letters if (c != 'n') { // append character to word word[word_length] = c; word_length++; } // if c = n and some letters're already in the word else if (word_length > 0) { // terminate current word word[word_length] = ' '; //write word to local dictionary dict[dict_index] = malloc(word_length + 1); strcpy(dict[dict_index],word); dict_index++; // prepare for next word word_length = 0; } } // make local dictioinary global global_dict = dict; } /** * Prints dictionary. */ void print(void) { for (int i = 0; i < dict_size; i++) printf("%s %pn",global_dict[i],global_dict[i]); } 解决方法
答案很简单,你将指针指向load()本地的变量,并在load()返回时释放它,因此它在print()中无效,导致未定义的行为.
你甚至评论过它 // local array <-- this is your comment not mine char *dict[dict_size]; 您有两种选择: >不要使用全局变量,与全局变量一起使用的模式没有任何好处,相反,它非常危险.您可以从函数load()返回动态分配的poitner,然后将其传递给print(). global_dict = malloc(dict_size * sizeof(*global_dict)); 为什么我不喜欢全局变量? >因为您可以在程序中执行您在程序中所做的操作,甚至不会收到编译器发出的警告. 但是当然,当你获得经验时,你不会做这种事情,所以它更多是你的错,而不是全局变量,但是看到程序员还在学习,使用全局变量来解决共享数据的问题是很常见的.在函数中,这是参数的用途. 所以使用不知道如何正确处理它们的全局变量是不好的,而是学习函数参数,你将解决所有需要全局变量通过程序中的不同函数传递数据而不使用全局变量的问题. 这是你自己的代码,我删除了global_dict变量,并在load()中使用了动态内存分配,我也对malloc()执行了一些错误检查,你应该改进那部分,如果你想要代码是健壮的,其余的是自我解释 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> // length of the longest word in dictionary #define LENGTH 45 // dictionary file #define DICTIONARY "large" // prototypes char **load(const char *dictionary); void print(char **); int main(void) { char **dictionary; dictionary = load(DICTIONARY); if (dictionary == NULL) return -1; print(dictionary); /* Don't forget to free resources,you might need to do it while the program is still running,leaked resources might quickly become a problem. */ for (int i = 0 ; dictionary[i] != NULL ; ++i) free(dictionary[i]); free(dictionary); return 0; } /** * Loads dictionary into memory. */ char **load(const char *dictionary) { // open dictionary file FILE *dict_file; size_t dict_size; char **dict; char word[LENGTH + 1]; size_t word_length; size_t dict_index; dict_file = fopen(dictionary,"r"); if (dict_file == NULL) /* you should be able to notify this */ return NULL; /* failure to open file */ // compute size of dictionary for (int c = fgetc(dict_file); c != EOF; c = fgetc(dict_file)) { // look for 'n' (one 'n' means one word) if (c == 'n') { dict_size++; } } // return to beginning of file fseek(dict_file,SEEK_SET); // local array dict = malloc((1 + dict_size) * sizeof(*dict)); /* ^ add a sentinel to avoid storing the number of words */ if (dict == NULL) return NULL; // variables for reading word_length = 0; dict_index = 0; // iteration over characters for (int c = fgetc(dict_file); c != EOF; c = fgetc(dict_file)) { // allow only letters if (c != 'n') { // append character to word word[word_length] = c; word_length++; } // if c = n and some letters're already in the word else if (word_length > 0) { // terminate current word word[word_length] = ' '; //write word to local dictionary dict[dict_index] = malloc(word_length + 1); if (dict[dict_index] != NULL) { strcpy(dict[dict_index],word); dict_index++; } // prepare for next word word_length = 0; } } dict[dict_index] = NULL; /* We put a sentinel here so that we can find the last word ... */ return dict; } /** * Prints dictionary. */ void print(char **dict) { for (int i = 0 ; dict[i] != NULL ; i++) printf("%s %pn",dict[i],(void *) dict[i]); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |