[英]Array of pointers to char * in c using qsort
在將字符串添加到指針數組時,最后一個字符串正在覆蓋它。 誰能告訴我,我的錯誤在哪里?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main (){
int ile = 3;
const char * slowa[ile];
for(int j = 0; j < ile; j++){
char string[30];
gets(string);
slowa[j] = string;
printf ("%s dodalem pierwsza\n",string);
}
for (int i = 0; i < ile; i++) {
printf ("%s numer %d\n",slowa[i],i);
}
return 0;
}
答案在以下兩行代碼中:
char string[30];
...
slowa[j] = string;
該分配將slowa[j]
設置為相同緩沖區的地址,而不進行復制。 因此,您放入緩沖區的最后一件事將由slowa[]
數組的所有元素引用,直到j-1
位置。
為了解決此問題,請在將值存儲在slowa
之前進行復制。 您可以使用非標准的strdup
,也可以使用malloc
+ strcpy
:
char string[30];
gets(string);
slowa[j] = malloc(strlen(string)+1);
strcpy(slowa[j], string);
在這兩種情況下,都需要在您slowa[]
分配了值的slowa[]
數組的所有元素上調用free
,以避免內存泄漏。
您總是指向chars數組,它是堆棧變量,僅在函數范圍內在本地分配,可能每個字符串聲明都將與循環中的上一個迭代位於同一地址。 您可以選擇不使用chars數組在每次循環迭代中分配內存,也可以使用數組,然后使用strdup為新字符串分配內存,例如
slowa[j] = strdup(string) :
正如其他人所說,您需要創建字符串的副本,否則將字符串設置為相同的地址,因此它們只會相互覆蓋。
另外,我認為使用fgets
不是gets
是一種更安全的方法。 這是因為gets
非常容易發生緩沖區溢出 ,而使用fgets
,您可以輕松檢查緩沖區溢出。
這是我前一陣子寫的一些代碼,類似於您要實現的代碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PTRS 3
#define STRLEN 30
int
string_cmp(const void *a, const void *b) {
const char *str1 = *(const char**)a;
const char *str2 = *(const char**)b;
return strcmp(str1, str2);
}
int
main(void) {
char *strings[PTRS];
char string[STRLEN];
int str;
size_t len, i = 0;
while (i < PTRS) {
printf("Enter a string: ");
if (fgets(string, STRLEN, stdin) == NULL) {
fprintf(stderr, "%s\n", "Error reading string");
exit(EXIT_FAILURE);
}
len = strlen(string);
if (string[len-1] == '\n') {
string[len-1] = '\0';
} else {
break;
}
strings[i] = malloc(strlen(string)+1);
if (strings[i] == NULL) {
fprintf(stderr, "%s\n", "Cannot malloc string");
exit(EXIT_FAILURE);
}
strcpy(strings[i], string);
i++;
}
qsort(strings, i, sizeof(*strings), string_cmp);
printf("\nSuccessfully read strings(in sorted order):\n");
for (str = 0; str < i; str++) {
printf("strings[%d] = %s\n", str, strings[str]);
free(strings[str]);
strings[str] = NULL;
}
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.