簡體   English   中英

memcpy(),未初始化的局部變量

[英]memcpy(), uninitialized local variable

最初,我跑在Ubuntu這個代碼和它的工作就好了不用任何警告。 但是,當我在Windows上的VS上運行它時,它說_operand1未初始化。 我想知道它怎么會出錯。

我知道不是強制轉換malloc的結果,但是VS只會不斷拋出警告。

程序應該采用9個字節的char數組。 第一字節代表算術運算,及其他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;

}

我真的不知道您會發生什么,但這是100%錯誤的。

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));

為什么選擇sizeof(int) buffer大概是一個指向字符數組的指針,並且沒有特別的理由選擇sizeof(int) ,因為結果只是傳遞給了atoi atoi函數只是使用一個指向以NUL終止的字符數組的指針, sizeof(int)只是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上運行它時,它說_operand1未初始化。 我想知道它怎么會出錯。

使用未初始化的值會導致未定義的行為,這意味着任何事情都可以發生。 這樣就可能出錯。


我知道不是強制轉換malloc的結果,但是VS只會不斷拋出警告。

您是否有機會將代碼編譯為C ++? 由於C ++不允許從void*進行隱式轉換,而C則允許。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM