Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ memcpy(),未初始化的局部变量_C++_Memcpy - Fatal编程技术网

C++ memcpy(),未初始化的局部变量

C++ memcpy(),未初始化的局部变量,c++,memcpy,C++,Memcpy,最初,我在ubuntu上运行了这段代码,它运行得很好,没有任何警告。但是,当我在windows上的VS上运行它时,它表示“操作数1未初始化”。我想知道怎么会出问题 我知道不投malloc的结果,但VS只是不断发出警告 程序应该采用9字节的字符数组。第一个字节表示算术运算,其他8个字节表示2个整数,每个4位数字4个字节。 代码如下: #include <stdio.h> #include <string.h> #include <stdlib.h> float

最初,我在ubuntu上运行了这段代码,它运行得很好,没有任何警告。但是,当我在windows上的VS上运行它时,它表示“操作数1未初始化”。我想知道怎么会出问题

我知道不投malloc的结果,但VS只是不断发出警告

程序应该采用9字节的字符数组。第一个字节表示算术运算,其他8个字节表示2个整数,每个4位数字4个字节。 代码如下:

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

float* calculate(char *, int *, int *);

int main() {

    char buffer[9];

    gets_s(buffer);

    int a, b;

    float* rez = calculate(buffer, &a, &b);

    printf("Operand1: %d, Operand 2: %d\n Result: %f\n", a, b, *rez);

    return 0;
}

float* calculate(char *buffer, int *a, int *b) {
    char operation;
    char *_operand1;
    char *_operand2;

    int operand1, operand2;

    memcpy(_operand1, buffer + 1, sizeof(int));
    _operand2 = (buffer + 5);

    operand1 = atoi(_operand1);
    operand2 = atoi(_operand2);

    operation = buffer[0];

    float *rez = (float *)malloc(sizeof(float));

    switch (operation) {
    case '0':
        *rez = (float)(operand1 + operand2);
        break;
    case '1':
        *rez = (float)(operand1 - operand2);
        break;
    case '2':
        *rez = (float)(operand1 * operand2);
        break;
    case '3':
        *rez = (float)operand1 / operand2;
        break;
    }

    return rez;

}

我真的不知道你期望会发生什么,但这是完全错误的

char *_operand1; /* uninitialized */
char *_operand2; /* uninitialized */

int operand1, operand2;

/* _operand1 is still uninitialized... */
memcpy(_operand1, buffer + 1, sizeof(int));
当你打电话给memcpy的时候,什么好事都不会发生。绝对最好的情况是您的程序将崩溃。然而,它可能不会崩溃,这是一件可怕的事情去思考…如果它没有崩溃,它在做什么?它可能在做你不想让它做的事情

进一步分析 代码总体上非常可疑

memcpy(_operand1, buffer + 1, sizeof(int));
为什么是sizeofint?缓冲区大概是一个指向字符数组的指针,并且没有特别的理由选择sizeofint,因为结果只是传递到atoi中。atoi函数只取一个指向以NUL结尾的字符数组的指针,sizeofint只是atoi结果的大小,而不是输入的大小

如何让它工作 以下是如何在不调用未定义行为的情况下执行此操作:

char tmp[5];

memcpy(tmp, buffer, 4); // don't use sizeof(int), just use 4
tmp[4] = '\0'; // add NUL terminator
int op0 = atoi(tmp);

memcpy(tmp, buffer + 5, 4);
// NUL terminator already present in tmp
int op1 = atoi(tmp);
请注意,当您将tmp传递给memcpy时,它将转换为char*类型的指针,该指针指向tmp的第一个元素。有点像做以下事情:

char tmp[5];
char *my_ptr = &tmp[0];
memcpy(my_ptr, ...);
您可以看到这与:

char *my_ptr; // uninitialized
memcpy(my_ptr, ...);
当我在windows上的VS上运行它时,它表示_operan1未初始化。我想知道怎么会出问题

使用未初始化的值会导致未定义的行为,这意味着允许发生任何事情。这就是它可能出错的原因

我知道不投malloc的结果,但VS只是不断发出警告


<>你是否将你的代码编译成C++?因为C++不允许从空隙*中隐式转换,而C确实如此。

难道不应该复制缓冲区中的内容吗?缓冲区是函数参数。我的意思是它可以在ubuntu上运行,而且它完全符合我的要求,但不能在windows上运行。这就是我来这里的原因。@sstefan:我可以向你保证Ubuntu上的错误。不管您使用的是什么系统,这都是100%错误的。@sstefan:请记住,函数不能初始化其参数。相反,memcpy将初始化其参数所指向的内容,但一般来说,函数不可能初始化其参数。如果您愿意,我可以发布屏幕截图。多次尝试times@sstefan:请不要发布屏幕截图。即使你的程序给出了正确的答案,它仍然是一个错误的程序。你也可以尝试使用Valgrind或Ubuntu编译上的地址消毒器运行该程序,并使用-fsanize=address链接。这将证明程序在Ubuntu上也是错误的,而不仅仅是Windows。如果你得到一个关于不空出的警告/错误,你就不用C编译器,但很可能是C++编译器。因此,这是C++,而不是C,仅仅用一个下划线来区分两个变量是非常糟糕的练习。别这样!警告非常明确。你认为memcpy在哪里复制数据?