簡體   English   中英

訪問作為參數傳遞的字符串會導致堆棧緩沖區溢出

[英]Accessing string that was passed as argument causes stack buffer overflow

我正在uni學習C,正在嘗試訪問傳遞到函數中的字符串(二進制數的字符串表示形式)以將其轉換為該字符串的整數表示形式。

例如。 "011"應返回3

字符串是反向輸入的比特流中的前3位。

char * temp_holder = (char *)malloc(sizeof(char) * 4);

int index_of_holder = 0;
for(int i = 2; i >= 0; i--){
    printf("%c", buffer[i]);
    temp_holder[index_of_holder] = buffer[i];
}
printf("\n");

int decimalValue = fromBinaryToInt(&temp_holder, 3);
printf("DECIMAL_VALUE: %d\n", decimalValue);

fromBinaryToInt函數為:

int fromBinaryToInt(char *string[], int length){

    for(int i = 0; i < length; i++){
        printf("%c", *string[i]);
    }

    int int_rep = strtol(*string, (char **)NULL, 2);

    printf("REP: %d\n", int_rep);

    return int_rep;
}

我得到的后續錯誤是:

== 21 ==錯誤:AddressSanitizer:PC 0x000000500cdf bp 0x7ffda9f47980 sp 0x7ffda9f47978-地址0x7ffda9f47a08上的堆棧緩沖區溢出-在0x7ffda9f47a08線程T0讀取大小8

我以為這可能是由於以零結尾的字符,所以我在fromBinaryToIntfor-loop修改了length變量(+/- 1),但並沒有改變任何東西。

我還認為for循環僅訪問第一個元素,僅此而已-但我的理解是我已經通過內存地址和塊的長度發送了消息,因此for循環應該可以訪問索引。

任何幫助將不勝感激,干杯:)

在此代碼中:

int index_of_holder = 0;
for(int i = 2; i >= 0; i--){
    printf("%c", buffer[i]);
    temp_holder[index_of_holder] = buffer[i];
}

index_of_holder從未更改,因此所有字符都放在temp_holder[0] 其余的temp_holder仍未初始化。

這個:

int fromBinaryToInt(char *string[], int length)

聲明string為指向char的指針的數組。 它確實傳遞了&temp_holder ,它可以被認為是一個指向char指針的數組的第一個元素的指針。 但是,更普通的用法是聲明一個指向char的簡單指針

int fromBinaryToInt(char *string, int length)

並將其傳遞給temp_holder ,如fromBinaryToInt(temp_holder, 3)

照原樣,在這里使用它:

printf("%c", *string[i]);

這需要數組的元素i i在循環中為0時,這很好,它將采用存在的第一個元素,該元素是char的指針,然后使用*對其進行引用並打印出來。 但是,當i為1時,它將嘗試采用數組的第二個元素。 該元素不存在,並且所產生的行為是不確定的。

如果參數只是char *string ,則此printf可以是:

printf("%c", string[i]);

並且,在調用strtol ,您只需傳遞string而不是*string

int int_rep = strtol(string, (char **)NULL, 2);

首先, index_of_holder行的錯誤, index_of_holder一直保持不變,請增加它。

temp_holder[index_of_holder] = buffer[i]; 

其次,在fromBinaryToInt() string僅是單個指針,因此您無法執行*string[i]); fromBinaryToInt() 在下一個printf語句中。

這是工作代碼

int fromBinaryToInt(char *string, int length){

        for(int i = 0; i < length; i++){
                printf("%c", string[i] ); /*since string is single pointer now you can do like before you did */
        }

        int int_rep = strtol(string, (char **)NULL, 2);

        printf("REP: %d\n", int_rep);

        return int_rep;
}
int main() {
        char * temp_holder = (char *)malloc(sizeof(char) * 4);
        char buffer[4] ="011";
        int index_of_holder = 0;
        for(int i = 2; i >= 0; i--){
                printf("%c", buffer[i]);
                temp_holder[index_of_holder] = buffer[i];
                index_of_holder++;
        }
        printf("\n");

        int decimalValue = fromBinaryToInt(temp_holder, 3);/* no need to pass address of temp_holder */
        printf("DECIMAL_VALUE: %d\n", decimalValue);
        return 0;
}

暫無
暫無

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

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