realloc导致的Segmentation Fault?
Segmentation Fault caused by realloc?
嘿,我正在尝试解决这个学校练习..
编写一个程序,不断读取字符串并将它们连接起来(将它们添加到单个字符串中)。串联应该发生在 returns 成功时为 1 或失败时为 0 的函数中。对于内存分配,仅使用 realloc!
我在调试程序时没有收到任何错误,但是当我尝试 运行 程序时,在我插入字符串后,唯一出现的是 "Segmentation Fault",这是怎么回事是?这是代码:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int cat(char **, char *);
int main(void)
{
char string[51];
char *output=NULL;
char choice;
do
{
printf("Please enter a string [<50 chars]: ");
fgets(string,50,stdin);
if(string[strlen(string)-1]=='\n') /* if newline was read as well */
string[strlen(string)-1]=0; /* discard it */
if(cat(&output,string))
printf("\n\nThe string now contains:\n%s\n",output);
else
{
printf("error: memory (re-)allocation failed!\n\n");
return 1; /* exit with error */
}
printf("Continue? (y/n) - ");
fgets(string,3,stdin); /* read input from keyboard - leave a safety buffer to account for read newline */
choice=string[0]; /* use the first character from the previous read as the choice */
} while(choice=='y' || choice=='Y');
free(output);
return 0;
}
int cat(char **dest, char *src)
{
int i;
int length1=strlen(src);
int length2=strlen(*dest);
int length3=length1+length2;
*dest=(char*)realloc(NULL,sizeof(*src));
printf("%p", *dest);
if(*dest==NULL) return 0; /* if allocation failed */
for(i=0;i<=length3;i++)
{
if(i<=length1)
(*dest)[i]=(*dest)[i];
else
(*dest)[i]=(src)[i];
}
free(src);
return 1;
}
您的代码至少有 5 个问题:
1) 你应该 free
只有你自己在堆上分配的东西。不要 free(src)
因为你传入的 src
指向堆栈内存(char string[51];
会自动释放)。
2) 您可能打算重新分配 dest
,并且 3) 您打算分配 length3
(+1 null-terminator).
大小的内存
*dest=(char*)realloc(*dest, length3 + 1);
4) 当 *dest
最初为 NULL 时 strlen(*dest)
会崩溃。
int length2=(*dest)?strlen(*dest):0;
5) 我认为您的 for-loop 不正确。它不会连接字符串,您的偏移量计算已关闭。
指针output
的初始值为NULL。但是在函数内部没有检查指针是否等于 NULL。因此,将函数 strlen
应用于指针会导致未定义的行为。
另外你还需要为终止零多预留一个字符。
函数中的内存未正确重新分配。而且sizeof( *src )
等于一个字节。
此声明
if(i<=length1)
(*dest)[i]=(*dest)[i];
没有多大意义。如果重新分配正确,重新分配的内存已经包含原始字符串。
您不应释放指针 src
,因为它不指向动态分配的内存。
该函数在演示程序中显示如下所示。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cat( char **dest, const char *src )
{
size_t n = strlen( src ) + ( *dest == NULL ? 0 : strlen( *dest ) );
char *tmp = realloc( *dest, n + 1 );
int success = tmp != NULL;
if ( success )
{
if ( *dest == NULL ) *tmp = '[=11=]';
*dest = tmp;
while ( *tmp ) ++tmp;
while ( ( *tmp++ = *src++ ) );
}
return success;
}
#define N 50
int main(void)
{
char *output = NULL;
char choice = 'n';
do
{
char string[N];
printf( "Please enter a string [<%d chars]: ", N );
fgets( string, sizeof( string ),stdin );
string[strcspn( string, "\n" )] = '[=11=]';
if ( cat( &output, string ) )
{
printf( "\nThe string now contains:\n\"%s\"\n\n", output );
}
else
{
printf( "error: memory (re-)allocation failed!\n\n" );
return 1; /* exit with error */
}
printf( "Continue? (y/n) - " );
fgets( string, 3, stdin ); /* read input from keyboard - leave a safety buffer to account for read newline */
choice = string[0]; /* use the first character from the previous read as the choice */
} while ( choice == 'y' || choice == 'Y' );
free( output );
return 0;
}
它的输出可能看起来像
Please enter a string [<50 chars]: Hi Stefano Feltre
The string now contains:
"Hi Stefano Feltre"
Continue? (y/n) - y
Please enter a string [<50 chars]:
The string now contains:
"Hi Stefano Feltre "
Continue? (y/n) - y
Please enter a string [<50 chars]: Let's learn C
The string now contains:
"Hi Stefano Feltre Let's learn C"
Continue? (y/n) - n
嘿,我正在尝试解决这个学校练习..
编写一个程序,不断读取字符串并将它们连接起来(将它们添加到单个字符串中)。串联应该发生在 returns 成功时为 1 或失败时为 0 的函数中。对于内存分配,仅使用 realloc!
我在调试程序时没有收到任何错误,但是当我尝试 运行 程序时,在我插入字符串后,唯一出现的是 "Segmentation Fault",这是怎么回事是?这是代码:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int cat(char **, char *);
int main(void)
{
char string[51];
char *output=NULL;
char choice;
do
{
printf("Please enter a string [<50 chars]: ");
fgets(string,50,stdin);
if(string[strlen(string)-1]=='\n') /* if newline was read as well */
string[strlen(string)-1]=0; /* discard it */
if(cat(&output,string))
printf("\n\nThe string now contains:\n%s\n",output);
else
{
printf("error: memory (re-)allocation failed!\n\n");
return 1; /* exit with error */
}
printf("Continue? (y/n) - ");
fgets(string,3,stdin); /* read input from keyboard - leave a safety buffer to account for read newline */
choice=string[0]; /* use the first character from the previous read as the choice */
} while(choice=='y' || choice=='Y');
free(output);
return 0;
}
int cat(char **dest, char *src)
{
int i;
int length1=strlen(src);
int length2=strlen(*dest);
int length3=length1+length2;
*dest=(char*)realloc(NULL,sizeof(*src));
printf("%p", *dest);
if(*dest==NULL) return 0; /* if allocation failed */
for(i=0;i<=length3;i++)
{
if(i<=length1)
(*dest)[i]=(*dest)[i];
else
(*dest)[i]=(src)[i];
}
free(src);
return 1;
}
您的代码至少有 5 个问题:
1) 你应该 free
只有你自己在堆上分配的东西。不要 free(src)
因为你传入的 src
指向堆栈内存(char string[51];
会自动释放)。
2) 您可能打算重新分配 dest
,并且 3) 您打算分配 length3
(+1 null-terminator).
*dest=(char*)realloc(*dest, length3 + 1);
4) 当 *dest
最初为 NULL 时 strlen(*dest)
会崩溃。
int length2=(*dest)?strlen(*dest):0;
5) 我认为您的 for-loop 不正确。它不会连接字符串,您的偏移量计算已关闭。
指针output
的初始值为NULL。但是在函数内部没有检查指针是否等于 NULL。因此,将函数 strlen
应用于指针会导致未定义的行为。
另外你还需要为终止零多预留一个字符。
函数中的内存未正确重新分配。而且sizeof( *src )
等于一个字节。
此声明
if(i<=length1)
(*dest)[i]=(*dest)[i];
没有多大意义。如果重新分配正确,重新分配的内存已经包含原始字符串。
您不应释放指针 src
,因为它不指向动态分配的内存。
该函数在演示程序中显示如下所示。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cat( char **dest, const char *src )
{
size_t n = strlen( src ) + ( *dest == NULL ? 0 : strlen( *dest ) );
char *tmp = realloc( *dest, n + 1 );
int success = tmp != NULL;
if ( success )
{
if ( *dest == NULL ) *tmp = '[=11=]';
*dest = tmp;
while ( *tmp ) ++tmp;
while ( ( *tmp++ = *src++ ) );
}
return success;
}
#define N 50
int main(void)
{
char *output = NULL;
char choice = 'n';
do
{
char string[N];
printf( "Please enter a string [<%d chars]: ", N );
fgets( string, sizeof( string ),stdin );
string[strcspn( string, "\n" )] = '[=11=]';
if ( cat( &output, string ) )
{
printf( "\nThe string now contains:\n\"%s\"\n\n", output );
}
else
{
printf( "error: memory (re-)allocation failed!\n\n" );
return 1; /* exit with error */
}
printf( "Continue? (y/n) - " );
fgets( string, 3, stdin ); /* read input from keyboard - leave a safety buffer to account for read newline */
choice = string[0]; /* use the first character from the previous read as the choice */
} while ( choice == 'y' || choice == 'Y' );
free( output );
return 0;
}
它的输出可能看起来像
Please enter a string [<50 chars]: Hi Stefano Feltre
The string now contains:
"Hi Stefano Feltre"
Continue? (y/n) - y
Please enter a string [<50 chars]:
The string now contains:
"Hi Stefano Feltre "
Continue? (y/n) - y
Please enter a string [<50 chars]: Let's learn C
The string now contains:
"Hi Stefano Feltre Let's learn C"
Continue? (y/n) - n