malloc的char *也改变了其他char *变量

时间:2014-07-15 07:18:13

标签: c memory-management malloc overlap atmega

我正在使用C编程atmega8535。我想使用ALFAT OEM模块将数据保存到闪存盘中。但是,我有问题,因为我要保存的数据会更改为中间程序中的其他变量(数据保存成功,但数据错误)。它发生在malloc之后。我已经malloc了变量数据。我正在使用超级终端来调试我的程序

这是我的代码。我只显示相关的

// Declare your global variables here
char* reply = NULL;
char* directory = NULL;
char* fileName = NULL;
char* getFileName = NULL;

void writeCommand(char* command){ //to give command to ALFAT
    //not related
}

void readCommand(){ //to request reply from ALFAT
    //related (because contains malloc and also change my variable) but I give another example
}

void get_ErrorCode(char errorCode[4]){ //to get errorCode from ALFAT's reply
    //not related
}

void get_Version(){ //to know ALFAT's version
    //not related
}

void mountUSB0(){ //to mount USB port 0
    //not related
}

void mountUSB1(){ //to mount USB port 1
    //not related
}

void get_fileName(){ //to get fileName from ALFAT's reply after N command
    //not related
}

int check_File(char port[1]){  //to check whether file already exists or not
    //related (because contains malloc and also change my variable) but I give another example
}

void separate_Directory(char* fullDir, char* data){ //to separate directory and fileName from fullDirectory "fullDir"
    int i,j;
    int numSlash = 0;               //numberOfSlash
    int curNumSlash = 0;            //currentNumberOfSlash

    //CHECK THE DATA BEFORE MALLOC
    printf("1st GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory);

    //count backslash '\'=0x5C
    for (i=0;i<strlen(fullDir);i++){
        if(fullDir[i]== 0x5C ) numSlash++;
    }

    //count number of char for directory
    i=0;
    curNumSlash = 0;
    while (curNumSlash != numSlash){
        if(fullDir[i]== 0x5C) curNumSlash++;
        i++;
    }

    //i = number of char for directory
    //number of char for filename = strlen(fullDir)-total char directory
    do{
        directory = (char *) malloc (i+1);
    }while(directory==NULL);
    do{
        fileName = (char *) malloc (strlen(fullDir)-i+1);
    }while(fileName==NULL);

    //CHECK THE DATA AFTER MALLOC (ALREADY CHANGED)
    printf("2nd GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory);

    //save into directory until last backslash
    i=0;
    curNumSlash = 0;
    while (curNumSlash != numSlash){
        if(fullDir[i]== 0x5C) curNumSlash++;
        directory[i] = fullDir[i];
        i++;
    }
    directory[i] = '\0';

    //remaining fullDir into fileName
    j=0;
    while (i < strlen(fullDir)){
        fileName[j] = fullDir[i];
        i++;
        j++;    
    } 
    fileName[j] = '\0';

    //CHECK THE DATA AGAIN (CHANGED INTO directory)
    printf("3rd GUNYUH data = %s, address data = %x, directory = %s, address directory = %x\n",data,data,directory,directory);
    printf("separate directory = %s, fileName = %s, fullDir = %s\n",directory,fileName,fullDir);
}


void writeData (char* data, char* fullDir, char port[1], char statFileHandler[16]){
//I omit that not related

    printf("1)!!!!!!!!!!!!!!!!DATA = %s, ADDRESS DATA = %x, DIRECTORY = %s, ADDRESS DIRECTORY = %x\n",data,*data,directory,*directory);
    separate_Directory(fullDir,data);
    printf("2)!!!!!!!!!!!!!!!!DATA = %s, ADDRESS DATA = %x, DIRECTORY = %s, ADDRESS DIRECTORY = %x\n",data,*data,directory,*directory);

//omitted
}

void main(){
    char* data;
    char* fullDir = NULL;
    char port[1]="";
    char statFileHandler[16];

    //omitted

    while(1){
         //omitted (also omit the mounting)


         do{
             data = (char *) malloc (strlen("meong")+1);   //+1 utk \0 
         }while(data==NULL);
         strcpy(data,"meong");
         data[strlen("meong")] = '\0';

         fullDir = (char *) malloc (strlen("\\f1\\nyan.txt")+1);
         strcpy(fullDir,"\\f1\\nyan.txt");
         fullDir[strlen("\\f1\\nyan.txt")] = '\0';
         for(i=0;i<strlen("\\f1\\nyan.txt");i++){
             fullDir[i] = toupper(fullDir[i]);
         } 

         //omit some printf for debugging
         printf("fullDir di main= %s\n",fullDir);   

         printf("data di main = %s\n",data);
         printf("address data di main = %x\n",*data);
         writeData (data, fullDir, port, statFileHandler);

         break;                        
      }

      while(1){}

      }
   }
}

检查GUNYUH部分。 HyperTerminal中的输出:

1st GUNYUH data = meong, address data = 196, directory = , address directory = 0
2nd GUNYUH data = , addressdata = 196, directory = , address directory = 196
3rd GUNYUH data = \F1\, address data = 196, directory = \F1\, address directory = 196

我的主要数据是“meong”。

在malloc之前的第一个GUNYUH,数据仍然是“meong”

在malloc之后的第二个GUNYUH,数据已经改变了

第3次GUNYUH定义目录后,数据也发生了变化。 (好吧因为地址也一样所以它指向同一个地址)

为什么改变了?

是因为缺乏内存问题吗?但是,当没有足够的堆内存时,malloc将返回NULL,因此它永远不会从循环中退出。我之前已经经历过堆内存的缺乏,它确实无法从循环中走出来。

我也经历过像这样的重叠。但这是因为我没有使用malloc。 (但是我没有检查地址并且去了静态数组,但没有足够的内存,所以回到动态,发现它需要malloc)

请帮忙吗?

1 个答案:

答案 0 :(得分:1)

这不是答案,但对于评论来说太大了。

您有以下错误:

  • 在四个不同的printf行中,您通过传递%s的空指针来导致未定义的行为。 (变量directory)。在未定义的行为开始后,所有赌注都将被取消。
  • 使用%x打印指针会导致未定义的行为。要打印指针,请使用%p并将指针强制转换为(void *)
  • 您在*THING
  • 的3个不同位置THING代替printf
  • Don't cast malloc,演员可能隐藏了指示错误的错误消息
  • for(i=0;i<strlen("\\f1\\nyan.txt");i++){行,i未声明。
  • 您未能加入stdio.hstdlib.h string.hctype.h
  • 您的代码中还有两个}而不是{
  • fullDir = (char *) malloc ...行之后,您不会检查malloc是否失败。

此代码不应编译。这让我相信你没有发布你的真实代码。您发布完全失败的代码非常重要。

您需要create a minimal program,测试该程序是否仍然显示问题,并且不加改变地发布该程序的代码。

这是因为“真实代码”中可能存在问题,但您发布的代码中却没有问题。由于您不知道问题出在哪里,因此无法确定是否包含导致问题的部分。

事实上,如果我修复了上面列出的所有错误并删除了main()末尾的无限循环,那么您的代码将为我编译并成功运行。这表明列出的点中的任何一个都是问题,或者问题出在您没有发布的代码中。