繁体   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