使用 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.
我试过:
- 创建一个新的动态分配指针;
- 如果(str)的当前字符不等于下一个字符,则在重新分配 (s) 后将其复制到 s 中。
问题是我在 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;
}
错误列表:
- 警告 C6308 'realloc' 可能 return 空指针:将空指针分配给 's',作为参数传递给 'realloc',将导致原始内存块被泄露。
您通常不需要为每个角色重新分配。所以懒惰的方法是最初分配一个与原始数组大小相同的数组,并在最后选择性地尝试缩小它:
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"
remove_multiple takes one parameter (a C string), and remove duplicates. it has to return the dynamically allocated string in the heap.
我试过:
- 创建一个新的动态分配指针;
- 如果(str)的当前字符不等于下一个字符,则在重新分配 (s) 后将其复制到 s 中。
问题是我在 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;
}
错误列表:
- 警告 C6308 'realloc' 可能 return 空指针:将空指针分配给 's',作为参数传递给 'realloc',将导致原始内存块被泄露。
您通常不需要为每个角色重新分配。所以懒惰的方法是最初分配一个与原始数组大小相同的数组,并在最后选择性地尝试缩小它:
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"