簡體   English   中英

使用qsort在C中指向char *的指針數組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM