typedef struct listaDocente nodoDocente;
struct listaDocente{ //teacherList
char Rut[12]; //ID
char Nombre[50]; //Name
char Correo[70]; //Email
char Cod_Curso[6]; //Grade_Code
char Asignatura[15]; //Grade_Name
nodoDocente *siguiente; //Next (Node)
};
int main(){
nodoDocente *D = ((nodoDocente * )malloc(sizeof(nodoDocente)));
strcpy(D->Nombre, "Charlie");
strcpy(D->Rut, "18123456");
strcpy(D->Asignatura, "EDD");
strcpy(D->Cod_Curso, "INS123");
strcpy(D->Correo, "charlie@test.com");
printf("%s\n", D->Nombre);
printf("%s\n", D->Rut);
printf("%s\n", D->Asignatura);
printf("%s\n", D->Cod_Curso);
printf("%s\n", D->Correo);
return 0;
}
首先,抱歉,如果有些单词是西班牙语。 我试图打印这些值,但我得到一个空白区域。
Charlie
18123456
INS123
charlie@test.com
它应该打印出EDD,就像这样。
Charlie
18123456
EDD
INS123
charlie@test.com
答案 0 :(得分:4)
您已声明:
char Cod_Curso[6];
并填写:
strcpy(D->Cod_Curso, "INS123");
但是INS123
之后是字符串\0
的终止字符。因此,您可能不会考虑6
个字符,而是INS123
字符串实际占用7
个字符。因此,您不能指望声明:
printf("%s\n", D->Asignatura);
在您使用上一行调用undefined-behavior时正常工作。
解决方案:声明大小为Cod_Curso
(或更多)的7
,如下所示:
char Cod_Curso[7];
答案 1 :(得分:4)
您已使用INS123
将Cod_Curso[6]
复制到strcpy
。现在strcpy
从src读取,直到它看到' \ 0'并将阅读的内容(包括' \ 0')复制到dest
。因此,这里将有7个字符复制到Cod_Curso
指向的缓冲区。
现在问题就在于此。目标缓冲区中分配的空间仅为6个字符。因此,将7个字符复制到其中将导致缓冲区溢出,即额外字符将被复制到不属于Cod_Curso
的存储器中,而是复制到堆栈中位于其上方的变量Asignatura[15]
。所以现在额外的角色' \ 0'已复制到Asignatura[0]
。
现在printf
打印'%s'
,直到它在传递的缓冲区中看到'\0'
。由于Asignatura[0]
为'\0'
,因此会打印一个空字符串。
<强>解决方案强>
最好使用像strncpy这样的安全版strcpy
。或者你可以增加缓冲区大小。
答案 2 :(得分:3)
不要忘记C中的字符串始终具有尾随\0
字符。所以你的:
INS123
写的
INS123\0
这是7个字符长度而不是6.所以你正在做的是在\0
的第一个字符上写一个额外的Asignatura
,因此它的长度变为0.
要解决此问题,您应该声明Cod_Curso
bi:
char Cod_Curso[7]; //Grade_Code
答案 3 :(得分:3)
字符串需要一个额外的字节来存储\0
,这使得一个字符数组被视为字符串。你在这违反了这条规则,
char Cod_Curso[6];
strcpy(D->Cod_Curso, "INS123");
这会将\0
覆盖到分配给其他变量的内存中,并在代码中生成UB。
如果您确定每个字符串的长度,您可以为char数组使用精确定义的长度,否则您可以将它们全部声明为char*
并将malloc声明为每个字符串以存储字符串为所有人提供或提供足够的数组长度(buffer
)。
此外,代码中存在内存泄漏。您应free
使用malloc
,calloc
和realloc
分配内存。
malloc
返回void*
,它隐式提升为C中的任何其他指针类型,因此您无需转换malloc
。