c++ unsigned char 数组分配 - 分段错误

Posted

技术标签:

【中文标题】c++ unsigned char 数组分配 - 分段错误【英文标题】:c++ unsigned char array allocation - segmentation fault 【发布时间】:2015-06-08 15:05:44 【问题描述】:

我无法弄清楚我从中得到分段错误的问题似乎是什么:

#include <stdio.h>
#include <stdlib.h>
#include <cstring>

void alloc(unsigned char *data) 
    data = (unsigned char *) malloc(20);
    memset(data, 0, 20);


void main() 
    unsigned char *data = NULL;
    int i;
    alloc(data);
    for (i = 0; i < 20; i++) 
        data[i] = i;
        printf("%d ", *(data + i));
    
    free(data);
    

Unsigned char 是 1 个字节,所以循环到 20 应该是正确的

【问题讨论】:

您需要将 unsigned char** 数据传递给 alloc 函数,然后使用 *data = (unsigned char *) malloc(20);或者像 Baum mit Augen 所说的使用对指针的引用。 如果你尝试像这样学习 C++,你需要扔掉你当前的书/教程并获得better one。 好吧,再看看它是 C++,因为他使用的是 &lt;cstring&gt;... 否则它看起来完全像 C 如果你使用了调试器(甚至是打印语句),你应该看到data在调用alloc之后没有改变,它仍然是NULL。这应该可以提供有关按值传递和临时变量发生的情况的线索。这就是调试代码很重要的原因——这样您 1) 不要浪费时间询问 SO,因为您会知道问题的原因和/或 2) 您将能够提出更集中的问题,例如“为什么我的指针没有改变?” 回滚了 OP 在标题和标签中特别询问 C++ 的更改,这不是 C,因为 &lt;cstring&gt;。此编辑与作者的意图相冲突。 【参考方案1】:
void alloc(unsigned char *data) 
    data = (unsigned char *) malloc(20);
    memset(data, 0, 20);

修改指针的本地副本。您可以通过引用传递它以使您的示例工作:

void alloc(unsigned char *&data) 
    data = (unsigned char *) malloc(20);
    memset(data, 0, 20);

【讨论】:

如果alloc()函数的参数是指针,不应该默认引用传递吗? @IoanFulgeanu C++ 中的所有内容(除了衰减为指针的普通 C 数组)默认情况下都是按值传递的,甚至是指针。 @IoanFulgeanu 不,指针本身仍然按值传递。你似乎很困惑,因为你可以使用指针的副本来访问它指向的任何东西,然后它就是你给函数的指针指向的同一个对象。【参考方案2】:

您的程序似乎是用 C 而不是 C++ 编写的。在 C++ 中,您应该使用 operator new [] 而不是 malloc。

函数的问题在于函数参数是它的局部变量。所以函数参数char *data 是其在 main 中声明的参数的副本,如

unsigned char *data = NULL;

因此函数alloc 中参数的任何更改都不会影响原始参数。退出函数后,参数(局部变量)将被销毁,main中的原始变量不会改变。

您有两种方法。您可以通过以下方式声明函数

void alloc(unsigned char **data) 
    *data = (unsigned char *) malloc( 20 );
    if ( *data ) memset( *data, 0, 20 );

然后这样称呼它

alloc( &data );

或者你用下面的方式声明函数

unsigned char * alloc() 
    unsigned char *data = (unsigned char *) malloc( 20 );

    if ( data ) memset( data, 0, 20 );

    return data;

并在 main 中调用它

data = alloc();

考虑到函数 main 应该像 C 一样被标记

int main( void )
^^^

在 C++ 中类似

int main()
^^^

【讨论】:

【参考方案3】:

您也可以返回指针,而不是将其传递给函数。

unsigned char *alloc() 
    unsigned char *data = (unsigned char *) malloc(20);
    memset(data, 0, 20);
    return data;

然后,

...
unsigned char *data = alloc();
int i;
...

您标记了 C++,但您的代码看起来像 C。如果您真的在尝试编写 C++,您不应该使用 malloc。使用 new[] 或适当的智能指针。

编辑:您正在使用 void main()。不要那样做。 What should main() return in C and C++?

【讨论】:

以上是关于c++ unsigned char 数组分配 - 分段错误的主要内容,如果未能解决你的问题,请参考以下文章

为数组中的 unsigned char 分配一个 short 的结果是啥?

如何将C++中string类型的字符串赋给unsigned char数组

C++怎么将 CString 转换成 unsigned char 的数组

将 unsigned char * 数组可视化为位图 [关闭]

如何将C++中string类型的字符串赋给unsigned char数组

c++ unsigned char 内存拷贝