繁体   English   中英

使用 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);
}

我已经知道我们的主要方法中的arr计数器不会保留所需的结果,但我仍然不明白为什么会出现错误。

请注意,您将NULL作为第三个参数传递:

rec(20, arr, 0); // 0 is NULL

你会得到一个取消引用它的段错误:

arr = realloc(arr, sizeof(int) * ++(*size)); // here size is `NULL`

尝试

rec(20, arr, size);

对于初学者,这些 memory 分配

int *arr = malloc(sizeof(int));
int *size = malloc(sizeof(int));

没有意义。 它们是多余的。

你可以写

int *arr = NULL;
size_t size = 0;

其次,变量大小已声明但未使用,因为您传递的变量不是 integer 常量 0

rec(20, arr, 0);

所以在 function rec

void rec(int x, int *arr, int *size);

the pointer size was initializer by the null pointer constant 0. That is size is a null pointer within the function and using a null pointer to access memory results in undefined behavior.

您还应该通过引用将指针传递给 function。 否则将其传递给 function 没有多大意义,因为 main 中的指针不会改变。

main 中的代码可能看起来像

int *arr = NULL;
size_t size = 0;

rec( 20, &arr, &size );

请注意,您应该释放所有已分配的 memory,当它不再使用时。

相应地,function 应声明为

void rec(int x, int **arr, size_t *size);

使用类型size_t而不是类型int因为这个无符号 integer 类型是 function realloc的第二个参数的类型。

通常,要获得 realloc 的结果,您应该使用中间变量,因为 function 可以返回 null 指针,当前指针将丢失。

还要注意 function 的调用是不安全的,并且可能由于这个 if 语句而导致无限递归

  if (x < 0) {
      rec(-x, arr, size);
      return;
  }

当用户传递给 function 时, 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;
}

它的 output 可能看起来像

x = -2147483648
-x = -2147483648

如您所见,否定变量 x 的值,您会得到相同的负值。 因此,最好将第一个 function 参数声明为具有unsigned int类型。

您的 function 可以按照以下方式查看示例,如下面的演示程序所示。

#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;
}

程序 output 是

987654321

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM