函数给出期望的输出然后异常终止
Function giving desired output and then terminating abnormally
我编写了以下程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* reversenew(char*);
char* reverseold(char*);
char* add(char*,char*);
char* standard(char*);
int main()
{
int i,n;
char *num1, *num2;
num1 = malloc(1000*sizeof(char));
num2 = malloc(1000*sizeof(char));
printf("Enter the numbers to be added\n");
gets(num1);
gets(num2);
printf("\n%s\n",add(num1,num2));
return 0;
}
char* reversenew(char* m)
{
char *k;
k = malloc(100*sizeof(char));
strcpy(k,m);
int i,n = strlen(k);
for(i = 0;i<n;i++)
k[i] = m[n-i-1];
return(k);
}
char* reverseold(char* m)
{
char temp;
int i,n = strlen(m);
for(i=0;i<n/2;i++)
{
temp = m[i];
m[i] = m[n-i-1];
m[n-i-1] = temp;
}
return m;
}
char* add(char* num1,char* num2)
{
char *n1,*n2;
int i,digit,carry = 0;
n1 = reversenew(standard(num1));
n2 = reverseold(standard(num2));
int n = (strlen(n1)>strlen(n2))?strlen(n1)+1:strlen(n2)+1;
while(strlen(n1)!=strlen(n2))
(strlen(n1)>strlen(n2))?(n2 = strcat(n2,"0")):(n1 = strcat(n1,"0"));
n1 = strcat(n1,"0");
n2 = strcat(n2,"0");
for(i=0;i<n;i++)
{
digit = (int)n1[i]+(int)n2[i]+carry-96;
n1[i] = (char)(48+(digit%10));
carry = digit/10;
}
n1 = reverseold(n1);
n2 = reverseold(n2);
if(n1[0] == 48)
n1++;
strcpy(n2,standard(n2));
return(n1);
}
char* standard(char* m)
{
int i = 0;
while(i < strlen(m))
{
if(m[0] == 48)
m+=1;
else
break;
}
return m;
}
add
函数将两个自然数以字符串形式相加,return以字符串形式得到结果。此函数提供所需的输出,然后对于小输入以 return 值 0 退出,对于大输入(例如,对于长度为 140 的输入字符串),以 return 值 3221226356 退出。我拿9重复140次,要加到同一个数。
请注意,reversenew
函数反转字符串并将结果存储在新字符串中,保持原始字符串可重复使用,而 reverseold
函数反转原始字符串。
此外,如果我在上一行之后 return 0;
之前编辑并输入 printf("\n5");
,那么它将按预期打印在输出 window 中,因此,我得出结论 add
功能正常。
请帮我解决问题。
当我运行你的程序用valgrind
输入下面的数字
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
我收到这些错误消息
==5279== Invalid write of size 1
==5279== at 0x483E0AC: strcpy (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5279== by 0x10929D: reversenew (add.c:27)
==5279== by 0x1093B0: add (add.c:51)
==5279== by 0x109251: main (add.c:19)
==5279== Address 0x4a5b184 is 0 bytes after a block of size 100 alloc'd
==5279== at 0x483A7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5279== by 0x109286: reversenew (add.c:26)
==5279== by 0x1093B0: add (add.c:51)
==5279== by 0x109251: main (add.c:19)
==5279==
valgrind: m_mallocfree.c:305 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 176, hi = 3761405300628338743.
This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata. If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away. Please try that before reporting this as a bug.
在函数 reversenew
中,您独立于字符串长度分配了一个 100 字节的块,并将原始字符串大小的数据写入其中。
这是未定义的行为。
你的 add
函数似乎工作正常,因为这个函数和后续的 printf
不关心你写的超出了分配的内存区域的末尾。
当函数main
returns时,系统会自动清理资源,例如释放所有内存并关闭所有文件。在您的情况下,此时会发生奇怪的事情,因为您破坏了动态内存分配的一些内部数据。结果,您会看到奇怪的 return 值。它也可能导致访问冲突或什么都没有或其他奇怪的事情,因为这是 undefined.
为 reversenew
中的结果字符串分配正确的大小。
我编写了以下程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* reversenew(char*);
char* reverseold(char*);
char* add(char*,char*);
char* standard(char*);
int main()
{
int i,n;
char *num1, *num2;
num1 = malloc(1000*sizeof(char));
num2 = malloc(1000*sizeof(char));
printf("Enter the numbers to be added\n");
gets(num1);
gets(num2);
printf("\n%s\n",add(num1,num2));
return 0;
}
char* reversenew(char* m)
{
char *k;
k = malloc(100*sizeof(char));
strcpy(k,m);
int i,n = strlen(k);
for(i = 0;i<n;i++)
k[i] = m[n-i-1];
return(k);
}
char* reverseold(char* m)
{
char temp;
int i,n = strlen(m);
for(i=0;i<n/2;i++)
{
temp = m[i];
m[i] = m[n-i-1];
m[n-i-1] = temp;
}
return m;
}
char* add(char* num1,char* num2)
{
char *n1,*n2;
int i,digit,carry = 0;
n1 = reversenew(standard(num1));
n2 = reverseold(standard(num2));
int n = (strlen(n1)>strlen(n2))?strlen(n1)+1:strlen(n2)+1;
while(strlen(n1)!=strlen(n2))
(strlen(n1)>strlen(n2))?(n2 = strcat(n2,"0")):(n1 = strcat(n1,"0"));
n1 = strcat(n1,"0");
n2 = strcat(n2,"0");
for(i=0;i<n;i++)
{
digit = (int)n1[i]+(int)n2[i]+carry-96;
n1[i] = (char)(48+(digit%10));
carry = digit/10;
}
n1 = reverseold(n1);
n2 = reverseold(n2);
if(n1[0] == 48)
n1++;
strcpy(n2,standard(n2));
return(n1);
}
char* standard(char* m)
{
int i = 0;
while(i < strlen(m))
{
if(m[0] == 48)
m+=1;
else
break;
}
return m;
}
add
函数将两个自然数以字符串形式相加,return以字符串形式得到结果。此函数提供所需的输出,然后对于小输入以 return 值 0 退出,对于大输入(例如,对于长度为 140 的输入字符串),以 return 值 3221226356 退出。我拿9重复140次,要加到同一个数。
请注意,reversenew
函数反转字符串并将结果存储在新字符串中,保持原始字符串可重复使用,而 reverseold
函数反转原始字符串。
此外,如果我在上一行之后 return 0;
之前编辑并输入 printf("\n5");
,那么它将按预期打印在输出 window 中,因此,我得出结论 add
功能正常。
请帮我解决问题。
当我运行你的程序用valgrind
输入下面的数字
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
我收到这些错误消息
==5279== Invalid write of size 1
==5279== at 0x483E0AC: strcpy (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5279== by 0x10929D: reversenew (add.c:27)
==5279== by 0x1093B0: add (add.c:51)
==5279== by 0x109251: main (add.c:19)
==5279== Address 0x4a5b184 is 0 bytes after a block of size 100 alloc'd
==5279== at 0x483A7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==5279== by 0x109286: reversenew (add.c:26)
==5279== by 0x1093B0: add (add.c:51)
==5279== by 0x109251: main (add.c:19)
==5279==
valgrind: m_mallocfree.c:305 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 176, hi = 3761405300628338743.
This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata. If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away. Please try that before reporting this as a bug.
在函数 reversenew
中,您独立于字符串长度分配了一个 100 字节的块,并将原始字符串大小的数据写入其中。
这是未定义的行为。
你的 add
函数似乎工作正常,因为这个函数和后续的 printf
不关心你写的超出了分配的内存区域的末尾。
当函数main
returns时,系统会自动清理资源,例如释放所有内存并关闭所有文件。在您的情况下,此时会发生奇怪的事情,因为您破坏了动态内存分配的一些内部数据。结果,您会看到奇怪的 return 值。它也可能导致访问冲突或什么都没有或其他奇怪的事情,因为这是 undefined.
为 reversenew
中的结果字符串分配正确的大小。