簡體   English   中英

最長字符串數組分段錯誤

[英]longest string array segmentation fault

編寫一個C函數longestStrInAr() ,它接受一個字符串數組strsize (>0)作為參數,並通過指針參數length返回最長字符串和最長字符串的長度。 如果兩個或多個字符串的最長字符串長度相同,則將第一個出現的字符串返回給調用函數。 例如,如果size5並且字符串數組是{ "peter", "john", "mary", "jane", "kenny"} ,那么最長的字符串是"peter"並且字符串長度是5將返回到調用函數

我在這里遇到分段錯誤,我不知道為什么。

#include <stdio.h>
#include <string.h>

#define N 20

char *longestStrInAr(char str[N][40], int size, int *length);

int main() {
    int i, size, length;   
    char str[N][40], first[40], last[40], *p, *result;
    char dummychar;   
    
    printf("Enter array size: \n");
    scanf("%d", &size);
    scanf("%c", &dummychar);
    for (i = 0; i < size; i++) {
        printf("Enter string %d: \n", i + 1);
        fgets(str[i], 40, stdin);
        if (p = strchr(str[i], '\n'))
            *p = '\0';   
    }  
    result = longestStrInAr(str, size, &length);
    printf("longest: %s \nlength: %d\n", result, length);         
    return 0;
}

char *longestStrInAr(char str[N][40], int size, int *length) {
    char *p;
    for (int i = 0; i < size; i++) {
        int j = 0; int max = 0, *length = 0;
        while (str[i][j++] != '\0') {
            max++;
        }
        if (max > *length) {
            *length = max;
            p = str[i];
        }
    }
    return p;
}

int j = 0; int max = 0, *length = 0;

不好。 此處聲明了一個新的指針變量length並將其初始化為NULL ,從而隱藏參數length
之后,這個lengthNULL )被取消引用,它會導致分段錯誤。

要將參數length指向的內容初始化為零,該行應為:

int j = 0, max = 0; *length = 0;

在函數longestStrInAr中, for循環中的代碼不正確:

    int j = 0; int max = 0, *length = 0;

定義 3 個局部變量: jmaxlength作為指向int的新指針,初始化為空指針。 length變量與函數參數具有相同的名稱,但定義在作為for語句主體的塊的范圍內,因此它會隱藏具有相同名稱的參數。 如果給出更高級別的警告( gcc -Wall -Wextra -Wshadowclang -Weverything ),編譯器會診斷出這個問題。

這導致了分段錯誤:當您稍后在if (max > *length)中取消引用此指針時,您有未定義的行為,因為length是一個空指針。

您可能只想使用參數並初始化*length ,您應該在for循環之前執行此操作。 另請注意,您應該將p初始化為p = str[0]對於所有字符串為空且發布的代碼返回未初始化指針的病態情況。 事實上,還有另一種特殊情況需要考慮:如果size0 ,函數應該返回NULL

main函數中也存在一些問題:如果size大於N ,您會讀取超出數組末尾的字符串。

這是修改后的版本:

#include <stdio.h>

#define N 20

char *longestStrInAr(char str[][40], int size, int *length);

int flush_input(void) {
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        continue;
    return c;
}

int main() {
    int i, size, length;   
    char str[N][40];
    char *result;
    
    printf("Enter array size: \n");
    if (scanf("%d", &size) != 1 || size < 0 || size > N) {
        fprintf(stderr, "invalid input\n");
        return 1;
    }
    // read and discard the rest of the input line
    flush_input();
    for (i = 0; i < size; i++) {
        printf("Enter string %d: \n", i + 1);
        str[i][0] = '\0';
        scanf("%39[^\n]", str[i]);
        flush_input();
    }  
    result = longestStrInAr(str, size, &length);
    printf("longest: %s \nlength: %d\n",
           result ? result : "(null)", length);         
    return 0;
}

char *longestStrInAr(char str[][40], int size, int *length) {
    char *p = NULL;
    *length = 0;
    if (size > 0) {
        for (int i = 0; i < size; i++) {
            int j = 0;
            while (str[i][j] != '\0')
                j++;
            if (*length < j) {
                *length = j;
                p = str[i];
            }
        }
    }
    return p;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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