访问作为参数传递的字符串会导致堆栈缓冲区溢出
Accessing string that was passed as argument causes stack buffer overflow
我正在 uni 学习 C,并试图访问传递给函数的字符串(二进制数的字符串表示形式),以将其转换为该字符串的整数表示形式。
例如。 "011"
应该 return 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:地址 0x7ffda9f47a08 上的堆栈缓冲区溢出,位于 pc 0x000000500cdf bp 0x7ffda9f47980 sp 0x7ffda9f47978
- 在 0x7ffda9f47a08 线程 T0
读取大小 8
我认为这可能是由于空终止字符造成的,所以我尝试修改 fromBinaryToInt
中 for-loop
中的 length
变量(+/- 1),但是那没有改变任何东西。
我还考虑过 for 循环只访问第一个元素,仅此而已 - 但我的理解是我已经发送了内存地址和块的长度,因此 for 循环应该可以访问索引.
如有任何帮助,我们将不胜感激,
干杯 :)
首先,下一行的错误,index_of_holder
一直保持不变,请增加它。
temp_holder[index_of_holder] = buffer[i];
其次,在 fromBinaryToInt()
中,string
只是单指针,因此您不能在下一个 printf
语句中执行 *string[i]);
。
这是工作代码
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;
}
在此代码中:
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);
我正在 uni 学习 C,并试图访问传递给函数的字符串(二进制数的字符串表示形式),以将其转换为该字符串的整数表示形式。
例如。 "011"
应该 return 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:地址 0x7ffda9f47a08 上的堆栈缓冲区溢出,位于 pc 0x000000500cdf bp 0x7ffda9f47980 sp 0x7ffda9f47978 - 在 0x7ffda9f47a08 线程 T0
读取大小 8我认为这可能是由于空终止字符造成的,所以我尝试修改 fromBinaryToInt
中 for-loop
中的 length
变量(+/- 1),但是那没有改变任何东西。
我还考虑过 for 循环只访问第一个元素,仅此而已 - 但我的理解是我已经发送了内存地址和块的长度,因此 for 循环应该可以访问索引.
如有任何帮助,我们将不胜感激, 干杯 :)
首先,下一行的错误,index_of_holder
一直保持不变,请增加它。
temp_holder[index_of_holder] = buffer[i];
其次,在 fromBinaryToInt()
中,string
只是单指针,因此您不能在下一个 printf
语句中执行 *string[i]);
。
这是工作代码
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;
}
在此代码中:
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);