使用 realloc 写入新字符串?

using realloc to write on a new string?

remove_multiple takes one parameter (a C string), and remove duplicates. it has to return the dynamically allocated string in the heap.

我试过:

问题是我在 realloc 上仍然有这个警告:“C6308 'realloc' 可能 return 空指针:将空指针分配给 's',它作为参数传递'realloc',将导致原始内存块被泄漏”,当我尝试调试程序时,我收到一条消息,它说我正在尝试在分配的内存之外写入。

这是我的代码:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char* remove_duplicates(const char* str) {
    char* s = malloc(sizeof(char)); 
    if (!s) {
        return NULL; 
    }
    for (size_t i = 0; str[i] != 0; i++) {
        
        
        if (str[i] != str[i + 1]) {
            s = realloc(s, 2 * sizeof(char));
            if (!s) {
                return NULL;
            }
            s[i] = str[i];
        }
    }

    return s; 
}



int main(void) {
    char str[] = "heyyyy"; 
    char* s = remove_duplicates(str); 
    printf("%s", s); 

    free(s); 
    return 0; 
}

错误列表:

您通常不需要为每个角色重新分配。所以懒惰的方法是最初分配一个与原始数组大小相同的数组,并在最后选择性地尝试缩小它:

char* remove_duplicates(const char* str) {
    char* s = malloc(1 + strlen(str)); // only allocate once with original size
    if (!s) {
        return NULL;
    }
    // keep track or current position, size and previous character
    char c, old = 0, *curr = s;
    size_t n = 0;
    while ((c = *str++) != '[=10=]') {
        // ignore duplicates
        if (c != old) {
            *curr++ = c;
            old = c;
            ++n;
        }
    }
    // add the terminating null
    *curr = '[=10=]';
    // optional shrink attempt
    s = realloc(s, n +  1);
    return s;
}

对于初学者来说,你的方法并不好。

该函数效率低下,因为其中有太多内存重新分配。

至于消息,那么这个

s = realloc(s, 2 * sizeof(char));

语句不安全,因为函数 realloc 可以 return 一个空指针。在这种情况下,先前分配的内存地址将丢失,导致内存泄漏。

您需要使用一个中间指针,它将被 realloc 赋值 return。

在此声明中

s = realloc(s, 2 * sizeof(char));

总是分配 2 个字节的内存。

左侧表达式中也使用了无效索引

s[i] = str[i];
^^^^

对于指针 s 你需要支持它的一个索引而不是 i

你首先需要判断有多少个不重复的相邻字符,然后只分配一次所需大小的数组。

这是一个演示程序。

#include <stdio.h>
#include <stdlib.h>

char * remove_duplicates( const char *s ) 
{
    size_t n = 0;
    
    for ( const char *p = s; *p; )
    {
        ++n;
        while ( *++p && p[0] == p[-1] );
    }
    
    char *result = malloc( n + 1 );
    
    if ( result != NULL )
    {
        char *p = result;
        do
        {
            *p = *s;
            while ( *s++ && s[0] == s[-1] );            
        } while ( *p++ );
    }
    
    return result;
}

int main( void )
{
    const char *s = "1223334444";
    
    printf( "\"%s\"\n", s );
    
    char *p = remove_duplicates( s );
    
    if ( p )    printf( "\"%s\"\n", p );

    free( p );
}

程序输出为

"1223334444"
"1234"