C比较2个字符串变成了内存分配问题

C Comparing 2 strings turned into memory allocation issue

首先让我说,我确实知道有很多标题完全相同的问题,但我没有在其中找到我要找的东西。我试着写了下面的代码,为了错误检查用户的输入,所以他不会给 2 个变量同名。不用说,它失败了,这就是我来这里的原因。在打印我作为字符串比较的字符串时,使用 printf("%s", temp[j].name); 工作正常,character-by-character 打印输出一系列字符,据我所知,这些字符不应该存在。我想知道这可能是怎么回事,如果有办法解决它,那么我实际上可以比较 2,而无需使用 string.h

中的内容

代码如下:

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

#define ARRAYLENGTH 20

typedef struct{
    char name[ARRAYLENGTH];
    char type[ARRAYLENGTH];
    char value[ARRAYLENGTH];
}variable;


int main(){
    int amount = 3;
    int i, j, k;
    variable * varray;
    variable * temp;
    int flag;
    int added = 1;

    varray = malloc(amount*sizeof(variable));
    if (varray == NULL){
        printf("error");
        return 1;
    }
        temp = malloc(amount*sizeof(variable));
    if (temp == NULL){
        printf("error");
        return 1;
    }
    printf("Give the name of variable # 1 \n");
    scanf("%s", varray[0].name);

    for (i = 1; i < amount; i++){
        flag = 0;
        while (flag == 0){
            printf("Give the name of variable # %d \n", i + 1);
            scanf("%s", temp[i].name);

            for (j = 0; j < added; j++){
                for (k = 0; temp[i].name[k] != '[=10=]'; k++){
                    printf("%c,", temp[i].name[k]);
                }
                printf("\n");
                for (k = 0; temp[i].name[k] != '[=10=]'; k++){
                    if (varray[j].name[k] != temp[i].name[k]){
                        flag = 1;
                        break;
                    }
                    if (varray[j].name[k] == temp[i].name[k]){
                        flag = 0;
                    }
                }
            }
            if (flag == 0){
                printf("The variable name you gave already exists, please choose another one. \n");
            }
            if (flag == 1){
                for (j = 0; j < ARRAYLENGTH; j++){
                    varray[i].name[j] = temp[i].name[j];
                }
            }
            if(flag == 1){
                added +=1;
            }
        }
    }
    for (i = 0; i < amount; i++){
        printf("%s \n", varray[i].name);
    }
    free(varray);
    free(temp);
}

代码编译没有问题,但是当我尝试 运行 它时,我发现,无论我作为用户输入什么,标志最终总是 1。代码块

printf("\n");
for (k = 0; k < ARRAYLENGTH; k++){
    printf("%c,", temp[i].name[k]);
}
printf("\n");

当用户输入名字 John 时,在 Visual Studio 2013 的 Developer 命令提示符下输出以下内容:

Give the name of variable # 1                                                                                                                         
John                                                                                                                                                  
Give the name of variable # 2                                                                                                                         
John                                                                                                                                                  
J,o,h,n,                                                                                                                                              
The variable name you gave already exists, please choose another one.                                                                                 
Give the name of variable # 2                                                                                                                         
George                                                                                                                                                
G,e,o,r,g,e,                                                                                                                                          
Give the name of variable # 3 
George                                                                                                                                                
G,e,o,r,g,e,                                                                                                                                          
G,e,o,r,g,e,                                                                                                                                          
The variable name you gave already exists, please choose another one.                                                                                 
Give the name of variable # 3                                                                                                                         
John                                                                                                                                                  
J,o,h,n,                                                                                                                                              
J,o,h,n,                                                                                                                                              
John                                                                                                                                                  
George                                                                                                                                                
John                 

我猜这个问题是因为系统分配给 tempvarray 的内存已经在其他地方使用了。此错误检查对于我必须做的项目至关重要,因此我将不胜感激能为解决此问题提供的任何帮助。提前致谢,

卢克赛克佩

问题出在你的打印逻辑上。

scanf 函数将用户输入写入数组,后跟一个终止字符“\0”。它不知道你的数组的大小 (20),所以它不会触及它实际上没有写入的数组部分。

而不是这个:

for (k = 0; k < ARRAYLENGTH; k++){

写:

for (k = 0; temp[i].name[k] != '[=11=]'; k++) {

请注意,您无需在此处检查数组末尾的 运行。相反,请确保用户字符串对于您的数组来说不是太大。请参阅 this 了解如何执行此操作。

编辑:此 post 不是要回答原始问题,而是要回答评论中 post 的后续问题。我试图将此合并到之前的答案中,但所有者拒绝了。原来如此。

你的 varray 比较的问题在于,至少在你显示的代码中,varray 从未被初始化。所以

if (varray[j].name[k] != temp[i].name[k])

有点像在内存中取出一个随机字节,将其分配给一个变量并执行此操作:

if (RandomByteValue != temp[i].name[k])

90% 的时间为真,因此将您的标记设置为 1。 本质上,你错过了

varray[i] = lastVariableGotFromUser

在每个主循环结束时。

--- 编辑:添加了对一般功能的小修正---

尝试添加:

int added = 1;

然后改变这个:

for (j = 0; j < amount; j++){

与 :

for (j = 0; j < added; j++){

并添加:

        if (flag == 1){
            // Your for loop
            added += 1;
        }

发生的事情是您遍历了未初始化且包含随机内存的 varray 字段。通过这些修改(如果我没有忘记一个,它应该可以工作。尝试始终将循环限制为仅有用的迭代。如果您知道只添加了一个变量,请不要遍历 3 个字段。

-------- 最后一次编辑以更正他的代码中的一个细节 ------

所以,你的整个 :

for (k = 0; temp[i].name[k] != '[=17=]'; k++){

可以删除。现在我也知道您不想使用 string.h,但是,重新编码 strcmp 并不是那么复杂。我们称它为

int comp_str(str, str2) // Returns 1 if they don't match, zero if they do.

然后将您的整个替换为 :

if (comp_str(temp[i].name, varray[j].name) == 0) {
    flag = 0;
    break;
}
else
    flag = 1;

您只想在分析完整个字符串后设置标志。所以将它传递给另一个函数,根据 return 值进行操作,它就起作用了!通常将您的代码切片。更容易 act/think 上。 (并且还避免在您的代码中出现 varray[j].name[k] != temp[i].name[k] 之类的东西,这种东西很长而且读起来不太舒服。)