在 C 中使用指针时出现地址边界错误
Getting address boundary error when working with pointers in C
下面的代码给了我一个terminated by signal SIGSEGV (Address boundary error)
:
void rec(int x, int *arr, int *size) {
if (x < 0) {
rec(-x, arr, size);
return;
}
arr = realloc(arr, sizeof(int) * ++(*size));
*(arr + (*size) - 1) = x % 10;
if (x % 10 != x)
rec(x / 10, arr, size);
}
int main() {
int *arr = malloc(sizeof(int));
int *size = malloc(sizeof(int));
*size = 0;
rec(20, arr, 0);
}
我已经知道 main 方法中的 arr
计数器不会保存所需的结果,但我仍然不明白为什么会出现错误。
请注意,您将 NULL
作为第三个参数传递:
rec(20, arr, 0); // 0 is NULL
你会得到一个取消引用它的段错误:
arr = realloc(arr, sizeof(int) * ++(*size)); // here size is `NULL`
试试
rec(20, arr, size);
对于初学者来说,这些内存分配
int *arr = malloc(sizeof(int));
int *size = malloc(sizeof(int));
没有意义。它们是多余的。
你可以直接写
int *arr = NULL;
size_t size = 0;
其次,声明了变量大小但未使用,因为您传递的不是变量而是整数常量 0
rec(20, arr, 0);
所以在函数内rec
void rec(int x, int *arr, int *size);
指针 size
由空指针常量 0 初始化。也就是说 size
是函数内的空指针,使用空指针访问内存会导致未定义的行为。
您还应该通过引用将指针传递给函数。否则将它传递给函数没有多大意义,因为 main 中的指针不会改变。
main 中的代码可能类似于
int *arr = NULL;
size_t size = 0;
rec( 20, &arr, &size );
注意当不再使用分配的内存时,应释放所有内存。
相应地函数应该这样声明
void rec(int x, int **arr, size_t *size);
使用类型size_t
而不是类型int
,因为这个无符号整数类型是函数realloc
.
的第二个参数的类型
一般来说,要获得 realloc 的结果,您应该使用一个中间变量,因为该函数可以 return 一个空指针,而当前指针将会丢失。
还要注意函数的调用是不安全的,会因为这个if语句导致无限递归
if (x < 0) {
rec(-x, arr, size);
return;
}
当用户将 x 的值传递给函数时等于 INT_MIN
。
考虑以下演示程序。
#include <stdio.h>
#include <limits.h>
int main(void)
{
int x = INT_MIN;
printf( "x = %d\n", x );
printf( "-x = %d\n", -x );
return 0;
}
它的输出可能看起来像
x = -2147483648
-x = -2147483648
如您所见,取负变量 x 的值会得到相同的负值。所以也许最好将第一个函数参数声明为 unsigned int
.
类型
您的函数可以按照下面的演示程序所示的方式查找。
#include <stdio.h>
#include <stdlib.h>
int rec( unsigned int x, unsigned int **arr, size_t *size )
{
const unsigned int Base = 10;
unsigned int *tmp = realloc( *arr, sizeof( int ) * ++*size );
int success = tmp != NULL;
if ( success )
{
*arr = tmp;
*( *arr + *size - 1 ) = x % Base;
if ( x % Base != x )
{
success = rec( x / Base, arr, size );
}
}
return success;
}
int main(void)
{
unsigned int *arr = NULL;
size_t size = 0;
rec( 123456789, &arr, &size );
for ( size_t i = 0; i < size; i++ )
{
printf( "%u", *( arr + i ) );
}
putchar( '\n');
free( arr );
return 0;
}
程序输出为
987654321
下面的代码给了我一个terminated by signal SIGSEGV (Address boundary error)
:
void rec(int x, int *arr, int *size) {
if (x < 0) {
rec(-x, arr, size);
return;
}
arr = realloc(arr, sizeof(int) * ++(*size));
*(arr + (*size) - 1) = x % 10;
if (x % 10 != x)
rec(x / 10, arr, size);
}
int main() {
int *arr = malloc(sizeof(int));
int *size = malloc(sizeof(int));
*size = 0;
rec(20, arr, 0);
}
我已经知道 main 方法中的 arr
计数器不会保存所需的结果,但我仍然不明白为什么会出现错误。
请注意,您将 NULL
作为第三个参数传递:
rec(20, arr, 0); // 0 is NULL
你会得到一个取消引用它的段错误:
arr = realloc(arr, sizeof(int) * ++(*size)); // here size is `NULL`
试试
rec(20, arr, size);
对于初学者来说,这些内存分配
int *arr = malloc(sizeof(int));
int *size = malloc(sizeof(int));
没有意义。它们是多余的。
你可以直接写
int *arr = NULL;
size_t size = 0;
其次,声明了变量大小但未使用,因为您传递的不是变量而是整数常量 0
rec(20, arr, 0);
所以在函数内rec
void rec(int x, int *arr, int *size);
指针 size
由空指针常量 0 初始化。也就是说 size
是函数内的空指针,使用空指针访问内存会导致未定义的行为。
您还应该通过引用将指针传递给函数。否则将它传递给函数没有多大意义,因为 main 中的指针不会改变。
main 中的代码可能类似于
int *arr = NULL;
size_t size = 0;
rec( 20, &arr, &size );
注意当不再使用分配的内存时,应释放所有内存。
相应地函数应该这样声明
void rec(int x, int **arr, size_t *size);
使用类型size_t
而不是类型int
,因为这个无符号整数类型是函数realloc
.
一般来说,要获得 realloc 的结果,您应该使用一个中间变量,因为该函数可以 return 一个空指针,而当前指针将会丢失。
还要注意函数的调用是不安全的,会因为这个if语句导致无限递归
if (x < 0) {
rec(-x, arr, size);
return;
}
当用户将 x 的值传递给函数时等于 INT_MIN
。
考虑以下演示程序。
#include <stdio.h>
#include <limits.h>
int main(void)
{
int x = INT_MIN;
printf( "x = %d\n", x );
printf( "-x = %d\n", -x );
return 0;
}
它的输出可能看起来像
x = -2147483648
-x = -2147483648
如您所见,取负变量 x 的值会得到相同的负值。所以也许最好将第一个函数参数声明为 unsigned int
.
您的函数可以按照下面的演示程序所示的方式查找。
#include <stdio.h>
#include <stdlib.h>
int rec( unsigned int x, unsigned int **arr, size_t *size )
{
const unsigned int Base = 10;
unsigned int *tmp = realloc( *arr, sizeof( int ) * ++*size );
int success = tmp != NULL;
if ( success )
{
*arr = tmp;
*( *arr + *size - 1 ) = x % Base;
if ( x % Base != x )
{
success = rec( x / Base, arr, size );
}
}
return success;
}
int main(void)
{
unsigned int *arr = NULL;
size_t size = 0;
rec( 123456789, &arr, &size );
for ( size_t i = 0; i < size; i++ )
{
printf( "%u", *( arr + i ) );
}
putchar( '\n');
free( arr );
return 0;
}
程序输出为
987654321