C - char*的malloc也改变其他char*变量



我正在使用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 = %xn",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 = %xn",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] = '';
    //remaining fullDir into fileName
    j=0;
    while (i < strlen(fullDir)){
        fileName[j] = fullDir[i];
        i++;
        j++;    
    } 
    fileName[j] = '';
    //CHECK THE DATA AGAIN (CHANGED INTO directory)
    printf("3rd GUNYUH data = %s, address data = %x, directory = %s, address directory = %xn",data,data,directory,directory);
    printf("separate directory = %s, fileName = %s, fullDir = %sn",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 = %xn",data,*data,directory,*directory);
    separate_Directory(fullDir,data);
    printf("2)!!!!!!!!!!!!!!!!DATA = %s, ADDRESS DATA = %x, DIRECTORY = %s, ADDRESS DIRECTORY = %xn",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  
         }while(data==NULL);
         strcpy(data,"meong");
         data[strlen("meong")] = '';
         fullDir = (char *) malloc (strlen("\f1\nyan.txt")+1);
         strcpy(fullDir,"\f1\nyan.txt");
         fullDir[strlen("\f1\nyan.txt")] = '';
         for(i=0;i<strlen("\f1\nyan.txt");i++){
             fullDir[i] = toupper(fullDir[i]);
         } 
         //omit some printf for debugging
         printf("fullDir di main= %sn",fullDir);   
         printf("data di main = %sn",data);
         printf("address data di main = %xn",*data);
         writeData (data, fullDir, port, statFileHandler);
         break;                        
      }
      while(1){}
      }
   }
}

检查GUNYUH部分。超级终端的输出:

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

my data in main is "meong".

第一个GUNYUH在malloc之前,数据仍然"meong"

malloc后的第二次GUNYUH,数据已经改变

3rd GUNYUH定义目录后,数据也发生了变化。(因为地址也是一样的所以它们指向相同的地址)

为什么会改变?

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

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

请帮忙?

这不是一个答案,但它太大了,不能评论。

你有以下bug:

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

这段代码不应该编译。这让我相信你并没有发布真正的代码。将准确地发布失败的代码是很重要的。

您需要创建一个最小程序,测试该程序仍然显示问题,并将该程序的代码原原本本地发布。

这是因为在"真实代码"中可能存在问题,而不是在您发布的代码中。因为你不知道问题在哪里,所以你不能确定你已经包含了导致问题的部分。

事实上,如果我修复上面列出的所有错误并删除main()末尾的无限循环,您的代码就可以编译并成功运行。这表明列出的点之一是问题,或者问题是在你没有发布的代码。

最新更新