【问题标题】:Bad output using structs and pointers使用结构和指针的错误输出
【发布时间】:2021-04-06 23:45:24
【问题描述】:

我正在尝试制作“对象”并稍后在 C 中管理它以“释放”和“重新分配”内存空间,但我在此代码中的输出存在问题:

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

typedef struct {
    // Param
    char name[16];
    char code[16];
    
} Employee;

void print(Employee *object)
{
    printf("\n \n - Name: [%s], Code: [%s]\n", object->name, object->code);
}


int main(){

    Employee *aPerson = (Employee *)malloc(sizeof(Employee));
    
    // Setting name:
    char select[1];
    do {    
        printf("\nWrite the employee name: ");
        scanf("%s", aPerson->name);
        printf("\nThe name is <%s>? (y/n): ", aPerson->name);
        scanf("%s", &select[0]);
        select[0] = tolower(select[0]);
    }while(select[0] != 'y');
    
    printf("\n[*]\t%s \n[]\t%s \n[&]\t%s", *aPerson, aPerson, &aPerson->name);
    printf("\n[->]\t%s", aPerson->name);
    print(aPerson);

}

我意识到,如果我输入“n”并再次设置名称,代码可以工作,但如果我在第一次尝试中获得正确的名称,代码就不起作用,当我遇到这个问题时我的输出是:

> ↑d)}·⌂

你的时间。

【问题讨论】:

  • 没有事件查看 scanf("%s", &amp;select[0]); 是未定义的行为。您至少需要 2 个字符:一个用于数据,一个用于终止零 - 您只有一个字符的空间。
  • 提示:一个数组通常是完全没用的。这相当于char,它不能保存长度> 0的C字符串。
  • 您可能希望使用char,然后使用scanf("%c", &amp;select) 作为单个字符。
  • 您应该使用if( scanf("%15s", aPerson-&gt;name) == 1 ) { ... } 始终放置一个宽度说明符,这样您就不会溢出数组边界,并始终检查返回值以确保将一些数据写入变量。
  • scanf 使用 %s 会自动添加一个 null,因此如果您的数组大小为 1,您的程序将写入无效的内存区域,从而导致不可预知的行为。我只使用 selected[2] 对其进行了测试,它确实有效。

标签: c memory


【解决方案1】:

我已经修复了你的代码,错误就行了:

char select[1];

您声明了一个长度为 1 的字符串,但由于在 C 中字符串是以空字符结尾的,因此“\0”字符没有空格。然后,当您调用 scanf 时,它会尝试写入空终止符,但正如我上面所说,堆栈上没有保留空间,这是未定义的行为。


这里是固定代码:

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

typedef struct {
    // Param
    char name[16];
    char code[16];
    
} Employee;

void print(Employee *object)
{
    printf("\n \n - Name: [%s], Code: [%s]\n", object->name, object->code);
}


int main(){

    Employee *aPerson = (Employee *)malloc(sizeof(Employee));
    
    // Setting name:
    char select[2];     // <---- Here is where I've made the correction
    do {    
        printf("\nWrite the employee name: ");
        scanf("%s", aPerson->name);
        printf("\nThe name is <%s>? (y/n): ", aPerson->name);
        scanf("%1s", select);
        select[0] = tolower(select[0]);
    }while(select[0] != 'y');
    
    printf("\n[*]\t%s \n[]\t%s \n[&]\t%s", *aPerson, aPerson, &aPerson->name);
    printf("\n[->]\t%s", aPerson->name);
    print(aPerson);

    free(aPerson);      // <------ I've added a free for the malloc.
}

【讨论】:

  • 问了什么问题?
  • ricxk 询问他的代码没有正确打印结构 Employee 中的字符串的原因,他的输出是随机字符。
猜你喜欢
  • 2023-03-15
  • 2021-09-23
  • 1970-01-01
  • 2023-01-14
  • 1970-01-01
  • 1970-01-01
  • 2021-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多