发出重新分配内存到字符串的问题

发布于 2025-02-03 07:52:03 字数 588 浏览 3 评论 0原文

C的新手并试图学习。 在这里,我尝试创建一个函数,该函数使用动态内存分配和ByRef复制字符串直至第一个空间。 似乎我在使用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]='\0';
    printf("\n%s\n",*c);

}

New to c and trying to learn.
Here I tried to create a function that copies a string until first space using dynamic memory allocation and byref.
Seems like I'm doing something wrong with the way I used realloc. Can you help me figure out what is wrong with the way I used dynamic memory allocation?

#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]='\0';
    printf("\n%s\n",*c);

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

把昨日还给我 2025-02-10 07:52:03
void f1(char** r, char* s) 
{
   // find size of new buffer
   size_t len = 0;
   while(s[len] != '\0' && s[len] != ' ') len++;

   *r = (char*)malloc(len + 1);

    memcpy(*r, s, len);

    (*r)[len] = '\0';
}
void f1(char** r, char* s) 
{
   // find size of new buffer
   size_t len = 0;
   while(s[len] != '\0' && s[len] != ' ') len++;

   *r = (char*)malloc(len + 1);

    memcpy(*r, s, len);

    (*r)[len] = '\0';
}
不如归去 2025-02-10 07:52:03

已经为一个字符分配了一个字符的内存

c =(char *) malloc(sizeof(char));

的第一次迭代中,

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);

因为在循环的第一次迭代中>变得等于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] != '\0' && 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] = '\0';
        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] != '\0' && !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] = '\0';
        }
    }

    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] = '\0';
        memcpy( result, s, n );
    }

    return result;
}

程序输出是

this

Before the function call there was already allocated memory for one character

c =(char *) malloc(sizeof(char));

In the first iteration of the while loop

int i=0;
while ((s[i])!=' ')
{
    (*c)[i]=s[i];
    i++;
    (*c)=(char *)realloc ((*c),sizeof(char)*i);
}

this memory was filled

    (*c)[i]=s[i];

and then again there was allocated memory only for one character

    (*c)=(char *)realloc ((*c),sizeof(char)*i);

because in the first iteration of the loop i becomes equal to 1. So in the second iteration of the loop there is an attempt to write outside the allocated memory that results in undefined behavior.

You need to write at least like

    *c = realloc ( *c, i + 1);

Also it will be more safer to use an intermediate pointer as for example

char *tmp = realloc ( *c, i + 1);
if ( tmp != NULL ) *c = tmp;

but in this case you will need also to change the function logic.

And the function should be declared like

int f1( char **c, const char *s);

and the condition of the should be changed like

while ( s[i] != '\0' && s[i] !=' ' )

Using your approach the program can look the following way.

#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] = '\0';
        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] != '\0' && !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] = '\0';
        }
    }

    return success;
}

The program output is

this

However such an approach with many memory reallocations is inefficient.

I would write the program the following way

#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] = '\0';
        memcpy( result, s, n );
    }

    return result;
}

Again the program output is

this
梦在深巷 2025-02-10 07:52:03

正如@unholysheep提到的那样,我用来分配内存的i太小。更改为(*t)=(char*)realloc(((*t),(i+1)*sizeof(char));,并且起作用。

As @UnholySheep mentioned the i I used to allocate memory was too small. Changed to (*t) = (char *)realloc((*t),(i+1)*sizeof(char)); and it worked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文