4

私はこの機能を作りました:

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 が何であるかは関係ありません。問題は、この関数が文字の配列を受け取ることです。

関数が常に「何か()」を受け取る文字の配列。私がやろうとしているのは、最後の2文字「()」を削除してから、関数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)

私は何が間違っているのかわからないので、どんな助けも感謝します。

4

3 に答える 3

3

これはstrncpy、宛先文字列を null で終了しないためです。

ソースの最初の num 文字を宛先にコピーします。num 文字がコピーされる前にソース C 文字列 (null 文字によって通知される) の末尾が見つかった場合、合計 num 文字が書き込まれるまで、destination にゼロが埋め込まれます。

source が num よりも長い場合、destination の最後に null 文字が暗黙的に追加されることはありません (したがって、この場合、destination は 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] = '\0';
于 2012-10-30T03:06:40.290 に答える
0

文字列を null で終了する必要があります。これは、パラメータ「センテンシア」と括弧を削除した結果にカウントされます

于 2012-10-30T03:07:04.720 に答える
0
 nombreFuncionSinParentesis = malloc(sizeof(char)*(strlen(nombreFuncion)-2));

上記は正しくありません。ヌル終端用のスペースも割り当てる必要があります。-2 が何をするのかわかりませんが、あなたがしようとしているものに +1 バイトを追加します。

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

コメントで示唆されているように、strncpy は使用しないでください。これは、UNIX の古いバージョンの特定のニーズに合わせて作成されたあいまいな関数です。この投稿を読むか、実際に別の回答へのコメントとして投稿された素敵な記事を読んでください。

free(nombreFuncion);

上記は非常に疑わしいですfree(sentencia)。関数の外側に割り当てられたものを実行しています。それが意図されている場合は、より良いプログラム設計を検討する必要があります。

于 2012-10-30T07:45:26.697 に答える