将内存重新分配给字符串的问题

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