【问题标题】:Make char vector from function从函数制作 char 向量
【发布时间】:2019-08-12 20:05:17
【问题描述】:

假设我想从给定的字符串(作为函数的参数)创建新字符串并返回新字符串。

在 main 中调用该方法时,从未生成新字符串,我不明白为什么。

这是我在 main 之外的函数中的代码:

char* new_name(char* name)
{
  char* res = (char*)malloc(strlen("recv") + strlen(name));
  if(res == null)
  {
    return null;
  }

  else
  {
    memcpy(&res, "recv_", strlen("recv_"));
    strcat(res, name);
  }
    return res;
}

我主要有:

char * result = new_name(name);

定义和给出“名称”的地方。

【问题讨论】:

  • 你应该按原样传递 res,而不是它的地址。
  • mallocing 是否有足够的空间容纳您的新字符串?好像太短了。

标签: c string function malloc


【解决方案1】:

  char* res = (char*)malloc(strlen("recv") + strlen(name));

由于后面的代码,您需要为“recv_”而不是“recv”分配,并为终止空字符分配1个位置,所以

char* res = (char*)malloc(strlen("recv_") + strlen(name) + 1);

 if(res == null)
 {
   return null;
 }

null 必须为 NULL

memcpy(&res, "recv_", strlen("recv_"));

必须

memcpy(res, "recv_", strlen("recv_") + 1);

否则你不修改分配的数组,而是从变量res的地址修改堆栈,你还需要放置终止的空字符,所以我只需在字符数上加1即可复制

注意使用 strcpy 是否更简单:strcpy(res, "recv_")


例子:

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

char* new_name(char* name)
{
  char* res = (char*)malloc(strlen("recv_") + strlen(name) + 1);

  if(res == NULL)
  {
    return NULL;
  }

  else
  {
    memcpy(res, "recv_", strlen("recv_") + 1); /* or strcpy(res, "recv_"); */
    strcat(res, name);
  }
  return res;
}

int main()
{

  char * result = new_name("foo");

  printf("'%s'\n", result);
  free(result);
  return 0;
}

编译和执行:

pi@raspberrypi:~ $ gcc -pedantic -Wall -Wextra m.c
pi@raspberrypi:~ $ ./a.out
'recv_foo'

valgrind下执行:

pi@raspberrypi:~ $ valgrind ./a.out
==22335== Memcheck, a memory error detector
==22335== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==22335== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==22335== Command: ./a.out
==22335== 
'recv_foo'
==22335== 
==22335== HEAP SUMMARY:
==22335==     in use at exit: 0 bytes in 0 blocks
==22335==   total heap usage: 2 allocs, 2 frees, 1,033 bytes allocated
==22335== 
==22335== All heap blocks were freed -- no leaks are possible
==22335== 
==22335== For counts of detected and suppressed errors, rerun with: -v
==22335== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

【讨论】:

  • 非常感谢!我在使用 memcpy 函数时遇到了问题。使用 strcpy 效果会更好!
  • @Xyz 是的,当您处理字符串时,最好将函数用于字符串而不是“内存”
【解决方案2】:

另一种解决方案可以是:

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

char *new_name(char *name) {
    char const prefix[] = "recv_";
    // Figure out size needed
    int sz = snprintf(NULL, 0, "%s%s", prefix, name);
    sz++; // make room for '\0' at end
    char *res = malloc(sz);
    if (res == NULL) {
        return NULL;
    }
    (void) snprintf(res, sz, "%s%s", prefix, name);
    return res;
}

或者,为了避免多次计算name 的长度,

char* new_name(char* name)
{
  char const prefix[] = "recv_";
  size_t const pre_len = sizeof prefix - 1U;
  size_t const name_len = strlen(name) + 1U;
  char* res = (char*)malloc(pre_len + name_len);
  if(res)
  {
    memcpy(res, prefix, pre_len);
    memcpy(res + pre_len, name, name_len);
  }
  return res;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多