c-使用strncpy.Valgrind抛出无效读取



我做了这个函数:

void procesar_llamadaAFuncion(t_proceso *unProceso, char *sentencia){
char *nombreFuncion = sentencia;
char *nombreFuncionSinParentesis = NULL;
string_trim(&nombreFuncion);
nombreFuncionSinParentesis = malloc(sizeof(char)*(strlen(nombreFuncion)-2));
strncpy(nombreFuncionSinParentesis, nombreFuncion, strlen(nombreFuncion)-2);
puts(nombreFuncionSinParentesis);
push_stack(unProceso->pcb->seg_stack, nombreFuncionSinParentesis, unProceso->pcb->program_counter);
unProceso->pcb->program_counter = get_pos_funcion(unProceso->pcb->funciones, nombreFuncionSinParentesis);
free(nombreFuncion);
free(nombreFuncionSinParentesis);

t_proceso是什么并不重要,问题是这个函数接收一个字符数组。

函数将接收的字符数组总是"something()",我想做的是删除最后两个字符"()"然后调用函数push_stack()。

问题是,当我运行Valgrind时,我得到的是:

==17129== Invalid read of size 1
==17129==    at 0x4C2BFD4: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17129==    by 0x50BFCEB: puts (ioputs.c:37)
==17129==    by 0x403D30: procesar_llamadaAFuncion (proceso.c:455)
==17129==    by 0x40313D: procesar_siguiente_instruccion (proceso.c:132)
==17129==    by 0x404B1A: probarProcesos (test.c:83)
==17129==    by 0x404C7F: main (test.c:111)
==17129==  Address 0x5436da8 is 0 bytes after a block of size 8 alloc'd
==17129==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17129==    by 0x403CDF: procesar_llamadaAFuncion (proceso.c:452)
==17129==    by 0x40313D: procesar_siguiente_instruccion (proceso.c:132)
==17129==    by 0x404B1A: probarProcesos (test.c:83)
==17129==    by 0x404C7F: main (test.c:111)

我不知道我做错了什么,所以任何帮助都将不胜感激。

这是因为strncpy不会null终止目标字符串:

将源的前num个字符复制到目标。如果在复制num个字符之前找到源C字符串的末尾(由null字符发出信号),则用零填充目的地,直到总共写入num个字符。

如果源长于num,则不会在目的地的末尾隐式附加null字符(因此,在这种情况下,目的地可能不是以null结尾的C字符串)。

这应该可以解决问题:

size_t nobmreLen = strlen(nombreFuncion)-2;
// Don't forget to add +1 for the null terminator
nombreFuncionSinParentesis = malloc(sizeof(char)*(nobmreLen+1));
strncpy(nombreFuncionSinParentesis, nombreFuncion, nobmreLen);
nombreFuncionSinParentesis[nobmreLen] = '';

您必须为null终止字符串。这对参数"sentencia"和删除括号的结果都很重要

nombreFuncionSinParentesis = malloc(sizeof(char)*(strlen(nombreFuncion)-2));

以上内容不正确,您还需要为null终止分配空间。我不明白-2的作用,但在你尝试的任何东西上加+1字节,这就是

malloc(sizeof(char)*(strlen(nombreFuncion)-2 + 1));

正如一条评论中所建议的那样,不应该使用strncpy,它是一个为古代unix版本的特定需求而编写的模糊函数。阅读这篇文章,或者作为对另一个答案的评论发布的漂亮文章。

free(nombreFuncion);

上面的情况非常可疑,您正在执行在函数之外分配的free(sentencia)。如果是这样的话,你应该考虑一个更好的程序设计。

相关内容

  • 没有找到相关文章

最新更新