将内存重新分配给字符串的问题
Issues reallocating memory to string
c 的新手,正在努力学习。
在这里,我尝试创建一个函数,该函数使用动态内存分配和 byref 复制字符串直到第一个 space。
好像我在使用 realloc 的方式上做错了什么。你能帮我弄清楚我使用动态内存分配的方式有什么问题吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void f1(char **c, char *s);
int main() {
char * s = "this is an example";
char *c;
c =(char *) malloc(sizeof(char));
f1(&c,s);
free(c);
}
void f1(char **c, char *s)
{
int i=0;
while ((s[i])!=' ')
{
(*c)[i]=s[i];
i++;
(*c)=(char *)realloc ((*c),sizeof(char)*i);
}
(*c)[i]='[=10=]';
printf("\n%s\n",*c);
}
正如@UnholySheep 提到的 i
我曾经分配的内存太小了。更改为 (*t) = (char *)realloc((*t),(i+1)*sizeof(char));
并且有效。
void f1(char** r, char* s)
{
// find size of new buffer
size_t len = 0;
while(s[len] != '[=10=]' && s[len] != ' ') len++;
*r = (char*)malloc(len + 1);
memcpy(*r, s, len);
(*r)[len] = '[=10=]';
}
在函数调用之前已经为一个字符分配了内存
c =(char *) malloc(sizeof(char));
在 while 循环的第一次迭代中
int i=0;
while ((s[i])!=' ')
{
(*c)[i]=s[i];
i++;
(*c)=(char *)realloc ((*c),sizeof(char)*i);
}
此内存已满
(*c)[i]=s[i];
然后又一次只为一个字符分配了内存
(*c)=(char *)realloc ((*c),sizeof(char)*i);
因为在循环的第一次迭代中 i
变得等于 1
。因此,在循环的第二次迭代中,尝试在分配的内存之外写入,导致未定义的行为。
你至少要写得像
*c = realloc ( *c, i + 1);
另外,使用中间指针会更安全,例如
char *tmp = realloc ( *c, i + 1);
if ( tmp != NULL ) *c = tmp;
但在这种情况下,您还需要更改功能逻辑。
并且该函数应该声明为
int f1( char **c, const char *s);
并且应该像
那样改变条件
while ( s[i] != '[=17=]' && s[i] !=' ' )
使用您的方法,程序可以看起来像下面这样。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int f1( char **s1, const char *s2 );
int main( void )
{
const char *s = "this is an example";
char *t = malloc( sizeof( char ) );
if ( t != NULL )
{
t[0] = '[=18=]';
f1( &t, s);
puts( t );
}
free( t );
}
int f1( char **s1, const char *s2 )
{
int success = 1;
for ( size_t i = 0; success && s2[i] != '[=18=]' && !isblank( ( unsigned char )s2[i] ); i++ )
{
char *tmp = realloc( *s1, i + 2 );
success = tmp != NULL;
if ( success )
{
*s1 = tmp;
( *s1 )[i] = s2[i];
( *s1 )[i+1] = '[=18=]';
}
}
return success;
}
程序输出为
this
然而,这种具有大量内存重新分配的方法效率低下。
我会这样写程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * f1( const char *s, const char *delim );
int main( void )
{
const char *s = "this is an example";
char *t = f1( s, " \t" );
if ( t != NULL )
{
puts( t );
}
free( t );
}
char * f1( const char *s, const char *delim )
{
size_t n = strcspn( s, delim );
char *result = malloc( n + 1 );
if ( result != NULL )
{
result[n] = '[=20=]';
memcpy( result, s, n );
}
return result;
}
程序输出同样是
this
c 的新手,正在努力学习。 在这里,我尝试创建一个函数,该函数使用动态内存分配和 byref 复制字符串直到第一个 space。 好像我在使用 realloc 的方式上做错了什么。你能帮我弄清楚我使用动态内存分配的方式有什么问题吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void f1(char **c, char *s);
int main() {
char * s = "this is an example";
char *c;
c =(char *) malloc(sizeof(char));
f1(&c,s);
free(c);
}
void f1(char **c, char *s)
{
int i=0;
while ((s[i])!=' ')
{
(*c)[i]=s[i];
i++;
(*c)=(char *)realloc ((*c),sizeof(char)*i);
}
(*c)[i]='[=10=]';
printf("\n%s\n",*c);
}
正如@UnholySheep 提到的 i
我曾经分配的内存太小了。更改为 (*t) = (char *)realloc((*t),(i+1)*sizeof(char));
并且有效。
void f1(char** r, char* s)
{
// find size of new buffer
size_t len = 0;
while(s[len] != '[=10=]' && s[len] != ' ') len++;
*r = (char*)malloc(len + 1);
memcpy(*r, s, len);
(*r)[len] = '[=10=]';
}
在函数调用之前已经为一个字符分配了内存
c =(char *) malloc(sizeof(char));
在 while 循环的第一次迭代中
int i=0;
while ((s[i])!=' ')
{
(*c)[i]=s[i];
i++;
(*c)=(char *)realloc ((*c),sizeof(char)*i);
}
此内存已满
(*c)[i]=s[i];
然后又一次只为一个字符分配了内存
(*c)=(char *)realloc ((*c),sizeof(char)*i);
因为在循环的第一次迭代中 i
变得等于 1
。因此,在循环的第二次迭代中,尝试在分配的内存之外写入,导致未定义的行为。
你至少要写得像
*c = realloc ( *c, i + 1);
另外,使用中间指针会更安全,例如
char *tmp = realloc ( *c, i + 1);
if ( tmp != NULL ) *c = tmp;
但在这种情况下,您还需要更改功能逻辑。
并且该函数应该声明为
int f1( char **c, const char *s);
并且应该像
那样改变条件while ( s[i] != '[=17=]' && s[i] !=' ' )
使用您的方法,程序可以看起来像下面这样。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int f1( char **s1, const char *s2 );
int main( void )
{
const char *s = "this is an example";
char *t = malloc( sizeof( char ) );
if ( t != NULL )
{
t[0] = '[=18=]';
f1( &t, s);
puts( t );
}
free( t );
}
int f1( char **s1, const char *s2 )
{
int success = 1;
for ( size_t i = 0; success && s2[i] != '[=18=]' && !isblank( ( unsigned char )s2[i] ); i++ )
{
char *tmp = realloc( *s1, i + 2 );
success = tmp != NULL;
if ( success )
{
*s1 = tmp;
( *s1 )[i] = s2[i];
( *s1 )[i+1] = '[=18=]';
}
}
return success;
}
程序输出为
this
然而,这种具有大量内存重新分配的方法效率低下。
我会这样写程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * f1( const char *s, const char *delim );
int main( void )
{
const char *s = "this is an example";
char *t = f1( s, " \t" );
if ( t != NULL )
{
puts( t );
}
free( t );
}
char * f1( const char *s, const char *delim )
{
size_t n = strcspn( s, delim );
char *result = malloc( n + 1 );
if ( result != NULL )
{
result[n] = '[=20=]';
memcpy( result, s, n );
}
return result;
}
程序输出同样是
this