如何重新分配字符指针以进行连接?

时间:2015-04-13 13:39:26

标签: c segmentation-fault token dynamic-memory-allocation

我编写了函数来标记整个字符串并连接每个标记的空间和字符串长度。我的职能是

主要功能

char *final_buff = NULL;

data_token(databuf,&final_buff);
之后我打电话给

free(final_buff);

功能:

int data_token(char *buffer,/*user_strinf*/
                    char **final_buff)/*store each token*/
{
    char *token_arr;
    char temp[10];
    int length = 0;
    token_arr = strtok(buffer,",");/*find first token*/
    while (token_arr != NULL)
    {
            printf("tokens--%s\n",token_arr);

            length = length + strlen(token_arr)+4;

            *final_buff = realloc(*final_buff,(length)*sizeof(char));/*allocate memory for the buffer*/

            if (NULL == *final_buff)
            {
                    printf("token memory allocation error\n");
                    exit(1);
            }

            strcat(*final_buff,token_arr);/*concatinate the token to buffer*/
            strcat(*final_buff," ");
            sprintf(temp,"%d",strlen(token_arr));
            strcat(*final_buff,temp);       /*concatinate buffer with string length */
            strcat(*final_buff," ");
            token_arr = strtok(NULL , ",");/*read next token */
    }

    return 1;
   }

这个分配在我调用这个函数时会起作用。因为我害怕在为该数组添加空格和整数时应该分配多长时间。这是对的吗 ?我得到了分段错误或核心转储。

3 个答案:

答案 0 :(得分:1)

该行

strcat(*final_buff,token_arr);/*concatinate the token to buffer*/

将在循环的第一次迭代中出现问题。

您还假设字符串的长度永远不会超过1个空格。您可以通过执行

删除该假设
   sprintf(temp,"%d",strlen(token_arr));

在循环早期并使用strlen(temp)计算*final_buff所需的长度。

我建议对while循环进行以下更新:

while (token_arr != NULL)
{
   printf("tokens--%s\n",token_arr);

   sprintf(temp,"%d",strlen(token_arr));

   // +3 -> two spaces and the terminating null character.
   length = length + strlen(token_arr) + strlen(temp) + 3;

   if ( *final_buff == NULL )
   {
      // No need to use length*sizeof(char). sizeof(char) is 
      // guaranteed to be 1
      *final_buff = malloc(length);
      (*final_buff)[0] = '\0';
   }
   else
   {
      *final_buff = realloc(*final_buff,(length));/*allocate memory for the buffer*/
   }

   if (NULL == *final_buff)
   {
      printf("token memory allocation error\n");
      exit(1);
   }

   strcat(*final_buff,token_arr); /*concatinate the token to buffer*/
   strcat(*final_buff," ");
   strcat(*final_buff,temp);      /*concatinate buffer with string length */
   strcat(*final_buff," ");
   token_arr = strtok(NULL , ",");/*read next token */
}

答案 1 :(得分:1)

*final_buff始终以空值终止 当它第一次使用realloc分配时,它可能不会以空值终止。您正在使用strcat写入它,这需要缓冲区已经以空值终止。

main中,您可以写

char *final_buff = malloc(sizeof(char));  // allocate 1 char
// todo: error checking
*final_buff = 0;  // null-terminate
data_token(databuf,&final_buff);

答案 2 :(得分:0)

如果要将值转换为字符串并且需要确保不溢出缓冲区,请使用snprintf()

http://man7.org/linux/man-pages/man3/printf.3.html

  

返回值

     

成功返回后,这些函数返回的数量   打印的字符(不包括用于结束输出的空字节)   字符串)。

     

函数snprintf()和vsnprintf()的写入不会超过大小   字节(包括终止空字节('\ 0'))。如果输出是   由于此限制而截断,则返回值为数字   本来可以使用的字符(不包括终止空字节)   如果有足够的空间,写入最终字符串。从而,   大小或更大的返回值意味着输出被截断。   (另见下文注释。)

     

如果遇到输出错误,则返回负值。