簡體   English   中英

程序以信號 SIGSEGV 終止,分段錯誤

[英]Program terminated with signal SIGSEGV, Segmentation fault

我得到了一個代碼片段https://leetcode.com/problems/letter-combinations-of-a-phone-number/discuss/397542/C-solution

我在網上提交,測試通過了。 然而,當我想在我的本地機器上進行測試時,我遇到了一個問題“程序以信號 SIGSEGV 終止,分段錯誤。”當它到達斷點的下一行 - return result時。

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

void catRes(char **result, char **phone, char *digits, char *tmp, int nowIndex, 
             int *resLen) {
    
    if (nowIndex == strlen(digits)) {
        tmp[nowIndex] = 0;
        result[(*resLen)] = (char *)malloc(strlen(tmp) + 1);
        strcpy(result[(*resLen)], tmp);
        (*resLen)++;
        return;
        
    }
    char *phoneData = phone[digits[nowIndex] - '0' - 2];
    for (int i = 0; i < strlen(phoneData); i++) {
        tmp[nowIndex] = phoneData[i];
        catRes(result, phone, digits, tmp, nowIndex + 1, resLen);
    }
}

char ** letterCombinations(char * digits, int* returnSize){
    char *phone[8] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    char **result = (char **)malloc(sizeof(char *) * 40);
    char tmp[strlen(digits) + 1];
    int resLen = 0;
    if (strlen(digits) == 0) {
        *returnSize = resLen;
        return result;
    }
    catRes(result, phone, digits, tmp, 0, &resLen);
    *returnSize = resLen;// set breakpoint here
    return result;
}


int main(){
    char s[] = {'2', '3'};
    char * digits = s;
    int * returnSize = NULL;
    char ** outcome = letterCombinations(digits, returnSize);
    ...
    return 0;

我在return result之前的那一行檢查了result的值,看起來還可以。 我需要一些幫助來告訴我問題出在哪里。

“程序以信號 SIGSEGV 終止,分段錯誤。”當它到達下一行斷點時 - 返回結果。

這是因為主要調用letterCombinations與 NULL for returnSize所以在:

 *returnSize = resLen;// set breakpoint here

你寫在地址0。


無論如何,在您有很多未定義的行為訪問非初始化值之前。 例如,在main中,數組s僅包含字符 '2' 和 '3' 並且不被 null 字符終止,因此strlen(digits)s之后具有未定義的行為讀取,只需執行char s[] = "23"; 為了避免這種情況。

valgrind下執行程序的結果:

pi@raspberrypi:/tmp $ valgrind ./a.out
==6789== Memcheck, a memory error detector
==6789== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6789== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==6789== Command: ./a.out
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x4866210: ??? (in /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so)
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x48662D4: ??? (in /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so)
==6789== 
==6789== Use of uninitialised value of size 4
==6789==    at 0x106B8: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x10498: catRes (c.c:8)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Use of uninitialised value of size 4
==6789==    at 0x10570: catRes (c.c:18)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x10498: catRes (c.c:8)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Use of uninitialised value of size 4
==6789==    at 0x10570: catRes (c.c:18)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x10498: catRes (c.c:8)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Use of uninitialised value of size 4
==6789==    at 0x10540: catRes (c.c:16)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Invalid read of size 4
==6789==    at 0x10540: catRes (c.c:16)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789==  Address 0xbd9670d0 is on thread 1's stack
==6789==  24 bytes below stack pointer
==6789== 
==6789== Use of uninitialised value of size 4
==6789==    at 0x10570: catRes (c.c:18)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x10498: catRes (c.c:8)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Use of uninitialised value of size 4
==6789==    at 0x104AC: catRes (c.c:9)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x48661D8: ??? (in /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so)
==6789== 
==6789== Use of uninitialised value of size 4
==6789==    at 0x48661DC: ??? (in /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so)
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x484762C: malloc (vg_replace_malloc.c:309)
==6789==    by 0x104DB: catRes (c.c:10)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Use of uninitialised value of size 4
==6789==    at 0x484BA2C: strcpy (vg_replace_strmem.c:513)
==6789==    by 0x10507: catRes (c.c:11)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Use of uninitialised value of size 4
==6789==    at 0x484BA48: strcpy (vg_replace_strmem.c:513)
==6789==    by 0x10507: catRes (c.c:11)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x484BA80: is_overlap (vg_replace_strmem.c:131)
==6789==    by 0x484BA80: strcpy (vg_replace_strmem.c:513)
==6789==    by 0x10507: catRes (c.c:11)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x484BA88: is_overlap (vg_replace_strmem.c:140)
==6789==    by 0x484BA88: is_overlap (vg_replace_strmem.c:127)
==6789==    by 0x484BA88: strcpy (vg_replace_strmem.c:513)
==6789==    by 0x10507: catRes (c.c:11)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x484BA8C: is_overlap (vg_replace_strmem.c:143)
==6789==    by 0x484BA8C: is_overlap (vg_replace_strmem.c:127)
==6789==    by 0x484BA8C: strcpy (vg_replace_strmem.c:513)
==6789==    by 0x10507: catRes (c.c:11)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Conditional jump or move depends on uninitialised value(s)
==6789==    at 0x484BAA8: strcpy (vg_replace_strmem.c:513)
==6789==    by 0x10507: catRes (c.c:11)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x1059B: catRes (c.c:19)
==6789==    by 0x106D3: letterCombinations (c.c:32)
==6789==    by 0x1072B: main (c.c:42)
==6789== 
==6789== Invalid write of size 4
==6789==    at 0x106DC: letterCombinations (c.c:33)
==6789==    by 0x1072B: main (c.c:42)
==6789==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6789== 
==6789== 
==6789== Process terminating with default action of signal 11 (SIGSEGV)
==6789==  Access not within mapped region at address 0x0
==6789==    at 0x106DC: letterCombinations (c.c:33)
==6789==    by 0x1072B: main (c.c:42)
==6789==  If you believe this happened as a result of a stack
==6789==  overflow in your program's main thread (unlikely but
==6789==  possible), you can try to increase the size of the
==6789==  main thread stack using the --main-stacksize= flag.
==6789==  The main thread stack size used in this run was 8388608.
==6789== 
==6789== HEAP SUMMARY:
==6789==     in use at exit: 304 bytes in 37 blocks
==6789==   total heap usage: 37 allocs, 0 frees, 304 bytes allocated
==6789== 
==6789== LEAK SUMMARY:
==6789==    definitely lost: 0 bytes in 0 blocks
==6789==    indirectly lost: 0 bytes in 0 blocks
==6789==      possibly lost: 0 bytes in 0 blocks
==6789==    still reachable: 304 bytes in 37 blocks
==6789==         suppressed: 0 bytes in 0 blocks
==6789== Rerun with --leak-check=full to see details of leaked memory
==6789== 
==6789== Use --track-origins=yes to see where uninitialised values come from
==6789== For lists of detected and suppressed errors, rerun with: -s
==6789== ERROR SUMMARY: 649 errors from 23 contexts (suppressed: 0 from 0)
Erreur de segmentation
pi@raspberrypi:/tmp $ 

我在主 function 的末尾添加了缺少的}並開始擺弄您的代碼一段時間。 在線上

    char ** outcome = letterCombinations(digits, returnSize);

在您的主要 function 中,您將returnSize作為NULL 現在,在您返回letterCombinations function 之前不久,您嘗試取消對NULL的引用,這就是導致SEGFAULT的原因。

現在,您似乎正試圖將一個值從您的letterCombinations function 內部傳播到外部。 可以通過將指向有效變量的指針傳遞給 function 來做到這一點,如下所示:

int main(){
    char s[] = {'2', '3'};
    char * digits = s;
    int returnSize;
    char ** outcome = letterCombinations(digits, &returnSize);
    return 0;
}

關於它為什么通過在線測試,我不能像你的主要問題那樣快速回答這個問題。

暫無
暫無

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

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