使用 strcat() 连接字符串时出现段错误

问题描述 投票:0回答:1

我想使用

strcat
将存储在结构中的每个新标签与 char
tags_cell_concat
中的 char 成员连接起来,如下所示:


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

#define BUFDATE 50
#define BIGBUFFLEN 1024

typedef struct 
{
  char date[BUFDATE];
  char tags[BUFDATE];
  char task[BUFDATE];
  char next_step[BUFDATE];
} Record;

int main()
{
  Record *records = (Record *) malloc(2*sizeof(Record));
  // all tags: "Hello world I am a string slice function"
  strcpy(records[0].tags, "Hello world");
  strcpy(records[1].tags, "string slice");
  strcpy(records[2].tags, "function");

  char tags_cell_concat[BIGBUFFLEN] = {0};
  char *chunk;
  char *pointer;

  for (size_t i=0; i<3; i++){
    strcat(tags_cell_concat, " ");
    pointer = records[i].date;
    while ((chunk = strsep(&pointer, " ")) !=NULL)
    {
      printf("%s\n", chunk);
    }
    if (strstr(tags_cell_concat, chunk) != NULL)
    {
      strcat(tags_cell_concat, chunk);
    }
  }
  return 0;
}

我在运行时遇到分段错误

编辑

在下面的评论和回答之后,上面的代码(我没有更改)确实存在第一个问题,因为没有为

records
分配足够的空间。我更改了代码以分配足够的内存,但问题仍然存在。如果第 36-39 行被注释掉,段错误问题就会消失,这向我表明问题可能出在使用
strcat()
函数时:

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

#define BUFDATE 50
#define BIGBUFFLEN 1024

typedef struct 
{
  char tags[BUFDATE];
} Record;

int main()
{
  size_t size = 6;
  Record *records = (Record *) malloc(size*sizeof(Record));
  strcpy(records[0].tags, "tag1 tag2");
  strcpy(records[1].tags, "tag3");
  strcpy(records[2].tags, "tag4 tag2");
  strcpy(records[3].tags, "tag1 tag5");
  strcpy(records[4].tags, "tag6 tag3");
  strcpy(records[5].tags, "tag7 tag2");
  strcpy(records[6].tags, "tag8 tag5");

  char tags_cell_concat[BIGBUFFLEN] = {0};
  char *chunk;
  char *pointer;

  for (size_t i=0; i<size; i++){
    strcat(tags_cell_concat, " ");
    pointer = records[i].tags;
    while ((chunk = strsep(&pointer, " ")) !=NULL)
    {
      printf("%s\n", chunk);
    }
    if (strstr(tags_cell_concat, chunk) != NULL) // line to comment out and get no seg fault
    { // line to comment out and get no seg fault
      strcat(tags_cell_concat, chunk); // line to comment out and get no seg fault
    } // line to comment out and get no seg fault
  }
  return 0;
}


这是现在的输出:

tag1
tag2
make: *** [runc] Segmentation fault: 11

编辑2

我再次更改了代码,因为我删除了记录中的一个记录,以便它对应于分配的内存。此外,我在 if 语句中检查

chunk
是否不是
NULL
(使用
(chunk !=NULL)
是否正确?)。但问题仍然存在。这是代码的最新版本:

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

#define BUFDATE 50
#define BIGBUFFLEN 1024

typedef struct 
{
  char tags[BUFDATE];
} Record;

int main()
{
  size_t size = 6;
  Record *records = (Record *) malloc(size*sizeof(Record));
  strcpy(records[0].tags, "tag1 tag2");
  strcpy(records[1].tags, "tag3");
  strcpy(records[2].tags, "tag4 tag2");
  strcpy(records[3].tags, "tag1 tag5");
  strcpy(records[4].tags, "tag6 tag3");
  strcpy(records[5].tags, "tag7 tag2");

  char tags_cell_concat[BIGBUFFLEN] = {0};
  char *chunk;
  char *pointer;

  for (size_t i=0; i<size; i++){
    strcat(tags_cell_concat, " ");
    pointer = records[i].tags;
    while ((chunk = strsep(&pointer, " ")) !=NULL)
    {
      printf("%s\n", chunk);
    }
    if ((strstr(tags_cell_concat, chunk) != NULL) && (chunk !=NULL)) // line to comment out and get no seg fault
    { // line to comment out and get no seg fault
      strcat(tags_cell_concat, chunk); // line to comment out and get no seg fault
    } // line to comment out and get no seg fault
  }
  return 0;
}

c pointers segmentation-fault char strcat
1个回答
3
投票

您仅将内存分配给类型为

Record
.

的两个元素的数组
  Record *records = (Record *) malloc(2*sizeof(Record));

所以访问数组元素的有效索引范围是

[0, 1]

但是您使用无效索引

2
访问数组的元素

  // all tags: "Hello world I am a string slice function"
  strcpy(records[0].tags, "Hello world");
  strcpy(records[1].tags, "string slice");
  strcpy(records[2].tags, "function");

导致未定义的行为。

以及这个 for 循环中的条件

 for (size_t i=0; i<3; i++){

也是无效的。

错误的原因之一是您使用了像

2
3
这样的幻数。而是使用命名常量。

也不是数组元素的所有数据成员都被初始化。所以这些陈述

pointer = records[i].date;
while ((chunk = strsep(&pointer, " ")) !=NULL)
{
  printf("%s\n", chunk);
}
if (strstr(tags_cell_concat, chunk) != NULL)
{
  strcat(tags_cell_concat, chunk);
}

还调用未定义的行为。

© www.soinside.com 2019 - 2024. All rights reserved.