使用realloc()

时间:2016-04-17 07:15:07

标签: c++ c string memory-management memmove

在我的函数中替换子字符串。如果输入子字符串比原始子字符串长,它会将输入字符串的一部分移出,以便为输入子字符串腾出空间。

我理解这会导致未定义的行为。我认为我应该能够通过使用realloc()来分配所需的空间但是还没有成功。

我尝试在memmove()之前添加它:

char *newspc = (char*)realloc(in,len+sublen);
in = newspc;

这是一个合理的策略吗?为这项行动腾出空间的正确方法是什么?

这是不使用realloc()的程序:

#include <iostream>
#include <string>
#include <string.h>

void replc(char* in, char* subin);

int main()
{
  char stmt[] = "replacing this $string ok";
  std::cout << stmt << "\n";
  replc(stmt, "longerstring");  //<<<4 characters longer breaks the program
  std::cout << stmt << "\n";

}

void replc(char* in, char* subin){
  uint8_t len = strlen(in);
  uint8_t aftok = strchr(strchr(in, '$'), ' ')-in;
  uint8_t dollar = strchr(in, '$')-in;
  uint8_t tklen = aftok - dollar;
  uint8_t sublen = strlen(subin);

   if(sublen <= tklen){
    //enough room for substring
    memmove(in+aftok-(tklen-sublen), in+aftok, (tklen-sublen)+1);
    memcpy(in+dollar, subin, sublen);
    in[len-(tklen-sublen)] = '\0';
   }
   else{
   //not enough room for substring
   // memory allocation should take place here?
    memmove(in+aftok+(sublen-tklen), in+aftok, (sublen-tklen)+1);
    memcpy(in+dollar, subin, sublen);
    in[len+(sublen-tklen)] = '\0';
   }

}

1 个答案:

答案 0 :(得分:1)

首先,如果你想使用realloc,你不必使用memmove,因为realloc将负责复制数据。

来自男人:

  

realloc()函数改变指向的内存块的大小   通过ptr来调整字节大小。内容将在以下范围内保持不变   该区域的起点最大为新旧尺寸。

此外,您只能对以前由malloc,realloc或calloc返回的指针使用realloc

  

除非ptr为NULL,否则必须先通过对malloc(),calloc()或realloc()的调用返回。

所以你需要在主

中使用malloc
char *stmt = malloc(strlen("replacing this $string ok") + 1);
if (stmt)
    stmt = "replacing this $string ok";

其次,如果要更改调用函数中指针的值,则需要在该指针(C样式)或引用(C ++样式)上使用指针,否则调用者中的指针将指向老地址。

原型的C风格示例:

void replc(char** in, char* subin);

分配(NewSize为整数):

*in = realloc(*in, NewSize);

(请记住,如果分配失败,malloc和realloc可以返回NULL)