我有以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX_FIL 15
#define MAX_COL 15
#define MAX 15*15
int frase_a_taula(char frase[], char taula[MAX_FIL][MAX_COL]) {
int i, j, k = 0, l, res = 0, final = 0;
for (i = 0; !final; i++) {
l = 0;
for (j = i; frase[j] != ' ' && frase[j] != '.'; j++) {
taula[k][l] = frase[j];
l++;
}
taula[k][l] = '\0';
if (frase[j] == '.') final = 1;
i = j;
k++;
res++;
}
return res;
}
void mescla_string_taula(char taula[MAX_FIL][MAX_COL], int n_filas, int coeficient) {
int n_mescles = 0, i, ind1, ind2;
if (coeficient == 2) {
n_mescles = n_filas / 2;
}
else if (coeficient == 1) {
n_mescles = n_filas / 4;
}
srand(time(NULL));
for (i = 0; i < n_mescles; i++) {
ind1 = rand() % n_filas;
ind2 = rand() % n_filas;
char *temp = (char *)malloc((strlen(taula[ind1]) + 1) * sizeof(char));
strcpy(temp, taula[ind1]);
strcpy(taula[ind1], taula[ind2]);
strcpy(taula[ind2], temp);
free(temp);
}
}
void alenteix_i_mescla_frase(char frase[MAX], char frase_lenta[MAX],
int velocitat, int coeficient) {
char taula[MAX_FIL][MAX_COL];
int i, j, len_frase_lenta;
int n_paraules = frase_a_taula(frase, taula);
mescla_string_taula(taula, n_paraules, coeficient);
strcpy(frase_lenta, taula[0]);
len_frase_lenta = strlen(frase_lenta);
for (i = 1; i < n_paraules; i++) {
if (velocitat == 1) {
if (i % 2 == 0) {
frase_lenta[len_frase_lenta] = '.';
frase_lenta[len_frase_lenta + 1] = '.';
frase_lenta[len_frase_lenta + 2] = '.';
len_frase_lenta += 3;
for (j = 0; j < strlen(taula[i]); j++) {
frase_lenta[len_frase_lenta] = taula[i][j];
len_frase_lenta++;
}
}
else {
frase_lenta[len_frase_lenta] = ' ';
len_frase_lenta++;
for (j = 0; j < strlen(taula[i]); j++) {
frase_lenta[len_frase_lenta] = taula[i][j];
len_frase_lenta++;
}
}
}
else if (velocitat == 2) {
frase_lenta[len_frase_lenta] = '.';
frase_lenta[len_frase_lenta + 1] = '.';
frase_lenta[len_frase_lenta + 2] = '.';
len_frase_lenta += 3;
for (j = 0; j < strlen(taula[i]); j++) {
frase_lenta[len_frase_lenta] = taula[i][j];
len_frase_lenta++;
}
}
}
frase_lenta[len_frase_lenta] = '.';
frase_lenta[len_frase_lenta+1] = '\0';
}
int main() {
printf("Introdueix nom del fitxer: ");
char path[MAX];
scanf("%s", path);
printf("Introdueix velocitat de parla: ");
int velocitat;
scanf("%d", &velocitat);
printf("Introdueix el coeficient de yodificacio: ");
int coef;
scanf("%d", &coef);
FILE* f = fopen(path, "r");
if (f == NULL) {
printf("Fitxer no trobat!");
}
else {
char line[MAX], frase_yodificada[MAX];
while (fgets(line, MAX, f) != NULL) {
alenteix_i_mescla_frase(line, frase_yodificada, velocitat, coef);
printf("%s\n", frase_yodificada);
}
printf("De processar...ha acabat, el fitxer\n");
}
return 0;
}和文件yodatest.txt
may the force be with you.
may the force be with you every day of your life.
avui fa un dia molt bonic.
hola.
si entrenes molt i ets perseverant arribaras lluny i tindras molts poders.
un dia em comprare una moto i anire volant fins a l'estrella de la mort.
no hi ha dia que no m'agradi mirar les estrelles de nit.在Ubuntu wsl中在Windows下编译和执行此代码时,我没有任何错误。但是,当我编译代码并在MacOs中执行它时,我得到了输出:
[1] 60023 trace trap ./main.exe
有时它正确执行,有时没有执行,但是我尝试在Ubuntu下执行了几次,并且总是得到正确的答案。此外,注释mescla_string_taula似乎有效,但我也不能肯定,因为错误的本质。基本上,这个函数只是改组矩阵。知道为什么会发生这种事吗?
一个正确的例子是:
Introdueix nom del fitxer: yodatest.txt
Introdueix velocitat de parla: 1
Introdueix el coeficient de yodificacio: 1
may the...force you...with be.
with the...force be...may of...every day...you your...life.
avui fa...un bonic...molt dia.
hola.
si molts...molt i...ets poders...arribaras lluny...i perseverant...entrenes tindras.
volant anire...em comprare...una fins...i dia...un moto...a l'estrella...de la...mort.
no de...ha dia...que nit...m'agradi mirar...les no...hi estrelles.
De processar...ha acabat, el fitxer发布于 2022-01-19 00:26:58
首先,我将展示如何使用调试器查找问题,因为这是一种不太为人所知的技术。
首先,我将提供的源代码复制并粘贴到文件yoda.c中,并将提供的测试输入复制到文件yodatest.txt中。(这就是为什么我们总是要求以文本形式提供源代码和测试数据,而不是以图像或其他任何形式提供。从我的web浏览器复制和粘贴东西到我的C编译环境只需要几秒钟,然后我就开始运行了。)
我编译了yoda.c并运行了它,得到了一个非常类似的错误:
Abort trap: 6这很有希望。(有时很难或不可能复制一个bug,从而使它更难诊断。)
接下来,我编译用于调试:
cc -g yoda.c并在调试器下运行程序:
$ lldb a.out
(lldb) target create "a.out"
Current executable set to 'a.out' (x86_64).
(lldb) run输入"run“运行程序。但是现在,当它崩溃时,我从调试器获得了相当多的输出:
2022-01-18 19:21:07.871139-0500 a.out[34597:99984533] detected source and destination buffer overlap
Process 34597 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x00007fff57022e3e libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
-> 0x7fff57022e3e <+10>: jae 0x7fff57022e48 ; <+20>
0x7fff57022e40 <+12>: movq %rax, %rdi
0x7fff57022e43 <+15>: jmp 0x7fff5701a0b8 ; cerror_nocancel
0x7fff57022e48 <+20>: retq
Target 0: (a.out) stopped.我可以输入"bt“以获得堆栈回溯:
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
* frame #0: 0x00007fff57022e3e libsystem_kernel.dylib`__pthread_kill + 10
frame #1: 0x00007fff57161150 libsystem_pthread.dylib`pthread_kill + 333
frame #2: 0x00007fff56f7f312 libsystem_c.dylib`abort + 127
frame #3: 0x00007fff56f7f485 libsystem_c.dylib`abort_report_np + 177
frame #4: 0x00007fff56fa3c2d libsystem_c.dylib`__chk_fail + 48
frame #5: 0x00007fff56fa3c3d libsystem_c.dylib`__chk_fail_overlap + 16
frame #6: 0x00007fff56fa3c6e libsystem_c.dylib`__chk_overlap + 49
frame #7: 0x00007fff56fa3e39 libsystem_c.dylib`__strcpy_chk + 64
frame #8: 0x000000010000084e a.out`mescla_string_taula(taula=0x00007ffeefbff550, n_filas=12, coeficient=1) at yoda.c:44
frame #9: 0x0000000100000907 a.out`alenteix_i_mescla_frase(frase="si entrenes molt i ets perseverant arribaras lluny i tindras molts poders.\n", frase_lenta="hola.", velocitat=1, coeficient=1) at yoda.c:56
frame #10: 0x0000000100000dd2 a.out`main at yoda.c:117
frame #11: 0x00007fff56ed3115 libdyld.dylib`start + 1这告诉我,对strcpy的冒犯调用是yoda.c第44行的调用。(这很方便,因为程序中有四个对strcpy的调用,否则我可能不知道是哪个调用导致了问题。)
显然这条线
strcpy(taula[ind1], taula[ind2]);在mescla_string_taula()中,可以将字符串复制到自身之上。在这种情况下,strcpy没有被定义为正确的行为。
一个被定义为在重叠情况下正常工作的函数是memmove。我用
memmove(taula[ind1], taula[ind2], strlen(taula[ind2])+1);现在这个计划似乎奏效了。
请注意,我没有更深入地分析问题,也没有检查其他问题,更不用说证明程序对所有输入都是正确的。(在评论中,鲁德·赫尔德曼发现了其他一些可疑代码。)但是在我的机器上,修改后的程序现在确实为这个测试用例生成了所需的输出。
https://stackoverflow.com/questions/70698277
复制相似问题