首页 > 解决方案 > 用 Malloc 连接两个字符串

问题描述

我一直在研究一个初学者 C 问题以尝试学习 C 的基础知识。我注意到下面的问题将从最后一个字符串起飞的索引开始并完成该字符串,但我想做的是将两个字符串连接在一起。

谁能指出我正确的方向?我正在尝试在没有 realloc 的情况下执行此操作来学习 xp。

char *string_dup(char *src)
{
  int len = strlen(src);
  char *src2 = malloc(len + 1);
  int i;
  for(i = 0; i < len; i++){
    *(src2 + i) = *(src + i);
  }
  *(src2 + len )='\0';
  return src2;
}

void *resize_memory(void *ptr, int old_size, int new_size)
{
    char *d = (char*)ptr;
    d = malloc(new_size);
}


char *url = string_dup("http://");
char *path = string_dup("website.com/");
int url_length = string_length(url);
int path_length = string_length(path);

int new_length = url_length - 1 + path_length;
char *new_url = resize_memory(url, url_length, new_length);
char *p = new_url + url_length;


while (*path != '\0') {
    *p = *path;
    p++;
    path++;
}

printf("Full path string: %s\n", new_url);

标签: c

解决方案


OP代码的问题:

尺寸错误

假设string_length()就像strlen().

// int new_length = url_length - 1 + path_length;
int new_length = url_length + 1 + path_length;

无效的调整大小

void *resize_memory(void *ptr, int old_size, int new_size) {
    char *d = (char*)ptr; // assign `d`
    d = malloc(new_size); // Why re-assigned `d`???
    // No use of old_size, new_size
    // No copying of existing data 
    // No freeing of old allocation  
}

我期待类似的东西

// return failure status
bool resize_memory(void **ptr_addr, size_t old_size, size_t new_size) {
  void *new_ptr = NULL;
  if (new_size > 0) {
    new_ptr = malloc(new_size);
    if (new_ptr) {  // Out of memory, leave *ptr_addr alone
      return true;
    }
    size_t min_size = old_size < new_size ? old_size : new_size;
    memcpy(new_ptr, *ptr_addr, min_size);
  }
  free(*ptr_addr);
  *ptr_addr = new_ptr;  
  return false;
}

realloc()使用分配连接字符串的方法。

  1. 寻找长度。
  2. 分配内存。
  3. 如果成功,复制第一个字符串,然后复制第二个字符串。附加一个 \0。

示例代码:

// s1, s2 may be NULL.  A NULL is treated as if ""
char *JoinStrings(const char *s1, const char *s2) {
  size_t len1 = s1 ? strlen(s1) : 0;
  size_t len2 = s2 ? strlen(s2) : 0;
  char *joined = malloc(len1 + len2 + 1);
  if (joined) {
    memcpy(joined, s1, len1);
    memcpy(joined + len1, s2, len2);
    joined[len1 + len2] = '\0';
  }
  return joined;
}

或通过snprintf()

char *JoinStrings(const char *s1, const char *s2) {
  size_t sz = (s1 ? strlen(s1) : 0) + (s2 ? strlen(s2) : 0) + 1;
  char *joined = malloc(sz);
  if (joined) {
    int len = snprintf(joined, sz, "%s%s", s1, s2);
    assert(len >= 0 && (unsigned) len < sz);  // Failure is very unexpected here.
  }
  return joined;
}

像 (*s1) += s2 一样连接

// *s1 is a prior allocated string, or NULL
 void ConcatenateString(char **s1, const char *s2) {
  char *joined = JoinStrings(*s1, s2);
  free(*s1);
  *s1 = joined;
}

推荐阅读