c - 由于字符串复制导致段错误

标签 c arrays string segmentation-fault

在下面的代码中,代码在第四次执行 while 循环后崩溃,并且在 strcpy 中崩溃

strcpy(userver_info[location].Tag_Name, field); 

调试时出现以下错误

Can't find a source file at "strcpy-sse2-unaligned.S"

我无法弄清楚导致崩溃的问题是什么,在面对上述问题后,我做了结构填充,认为这可能是问题所在,但即使这样也无法解决,任何人都可以告诉我为什么是这样代码崩溃。

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


#define BUFFER_SIZE               1024
#define NUM_OF_UNDERLYING_SERVER  0


#define SHM_ADDR_LEN              15
#define SERVER_NAME_LEN           25
#define TAG_NAME_LEN              25
#define TAG_DESC_LEN              30
#define ACCESS_LEVEL_LEN          5
#define DATA_TYPE_NAME_LEN            10

typedef struct {
  char    SHM_Location[SHM_ADDR_LEN];
  char    Server_ID[SERVER_NAME_LEN];
  char    Tag_Name[TAG_NAME_LEN];
  int     Tag_ID;
  char    Tag_Description[TAG_DESC_LEN];
  char    Access_Level[ACCESS_LEVEL_LEN];
  char    Data_Type[DATA_TYPE_NAME_LEN];
}u_server_info;

typedef struct {
  int num_of_tags;
  u_server_info *underlying_server_data;
}opcua_u_server;



void parse_underlying_opcua_server(char * buffer, u_server_info *userver_info) {

  static int location = 0;
  char *field;
  /* get SHM_Location */
  field = strtok(buffer,",");
  strcpy(userver_info[location].SHM_Location, field);

  /* get Server_ID */
  field=strtok(NULL,",");
  strcpy(userver_info[location].Server_ID, field);

  /* get Tag_Name */
  field = strtok(NULL,",");
  strcpy(userver_info[location].Tag_Name, field);

  /* get Tag_ID */
  field=strtok(NULL,",");
  userver_info[location].Tag_ID = atoi(field);

  /* get Tag_Description */
  field = strtok(NULL,",");
  strcpy(userver_info[location].Tag_Description, field);

  /* get Access_Level */
  field = strtok(NULL,",");
  strcpy(userver_info[location].Access_Level, field);

  /* get Data_Type */
  field = strtok(NULL,",");
  strcpy(userver_info[location].Data_Type, field);

  /* display the result */
  printf("%s\t %s\t %s\t %d\t %s\t %s\t %s\n",
          userver_info[location].SHM_Location,
          userver_info[location].Server_ID,
          userver_info[location].Tag_Name,
          userver_info[location].Tag_ID,
          userver_info[location].Tag_Description,
          userver_info[location].Access_Level,
          userver_info[location].Data_Type);

  location++;
}


int get_line_count(char *filename) {

  FILE *fp;
  int line_count = 0;
  char c;
  fp = fopen(filename, "r");
  if (fp == NULL){
      printf("Unable to open file '%s' to count lines\n",filename);
      return -1;
  }
  for (c = getc(fp); c != EOF; c = getc(fp))
      if (c == '\n') // Increment count if this character is newline
          line_count = line_count + 1;
  fclose(fp);
  return line_count;
}

int main(int argc, char **argv)
{
  char filename[] = "underlying_server.csv";
  char buffer[BUFFER_SIZE];
  FILE *fp;
  int tags_count = 0;
  opcua_u_server *ua_server = NULL;

  /* open the CSV file */
  fp = fopen(filename,"r");
  if( fp == NULL) {
      printf("Unable to open file '%s'\n",filename);
      exit(EXIT_FAILURE);
  }

  tags_count = get_line_count(filename);
  /* Allocate memmory for each Underlying server */
  ua_server= malloc(sizeof(opcua_u_server));
  if (ua_server == NULL) {
      printf("Malloc failed");
      exit(EXIT_FAILURE);
  }
  /* Allocate memory for each underlying server tag information */
  ua_server[NUM_OF_UNDERLYING_SERVER].underlying_server_data =
          malloc(tags_count * sizeof(ua_server->underlying_server_data));

  if (ua_server[NUM_OF_UNDERLYING_SERVER].underlying_server_data == NULL) {
      printf("Malloc failed");
      exit(EXIT_FAILURE);
  }
  /* process the data */
  while(fgets(buffer,BUFFER_SIZE,fp)) {

      parse_underlying_opcua_server(buffer,
                      ua_server[NUM_OF_UNDERLYING_SERVER].underlying_server_data);

  }
  ua_server->num_of_tags = tags_count;
  /*Reset the value for next server*/
  tags_count = 0;
  /* close file */
  fclose(fp);

  return(0);
}

我的underlying_server.csv是这样的

1000,Server_1,Tag_1,3000,Created_tag_3000,AR,BOOL
1001,Server_1,Tag_2,3001,Created_tag_3001,AR,BOOL
1002,Server_1,Tag_3,3002,Created_tag_3002,AR,BOOL
1003,Server_1,Tag_4,3003,Created_tag_3003,AR,BOOL
1004,Server_1,Tag_5,3004,Created_tag_3004,AR,REAL
1005,Server_1,Tag_6,3005,Created_tag_3005,AR,REAL
1006,Server_1,Tag_7,3006,Created_tag_3006,AW,REAL
1007,Server_1,Tag_8,3007,Created_tag_3007,AW,REAL
1008,Server_1,Tag_9,3008,Created_tag_3008,AW,REAL
1009,Server_1,Tag_10,3009,Created_tag_3009,AW,REAL
1010,Server_1,Tag_11,3010,Created_tag_3010,AW,REAL
1011,Server_1,Tag_12,3011,Created_tag_3011,AW,DWORD
1012,Server_1,Tag_13,3012,Created_tag_3012,AW,DWORD
1013,Server_1,Tag_14,3013,Created_tag_3013,AR,DWORD
1014,Server_1,Tag_15,3014,Created_tag_3014,AR,DWORD
1015,Server_1,Tag_16,3015,Created_tag_3015,AR,DWORD
1016,Server_1,Tag_17,3016,Created_tag_3016,AR,DWORD
1017,Server_1,Tag_18,3017,Created_tag_3017,AR,DWORD
1018,Server_1,Tag_19,3018,Created_tag_3018,AR,DWORD
1019,Server_1,Tag_20,3019,Created_tag_3019,AR,DWORD
1020,Server_1,Tag_21,3020,Created_tag_3020,AR,DWORD
1021,Server_1,Tag_22,3021,Created_tag_3021,AW,BOOL
1022,Server_1,Tag_23,3022,Created_tag_3022,AW,BOOL
1023,Server_1,Tag_24,3023,Created_tag_3023,AW,BOOL
1024,Server_1,Tag_25,3024,Created_tag_3024,AW,BOOL
1025,Server_1,Tag_26,3025,Created_tag_3025,AW,BOOL
1026,Server_1,Tag_27,3026,Created_tag_3026,AW,DWORD
1027,Server_1,Tag_28,3027,Created_tag_3027,AR,DWORD
1028,Server_1,Tag_29,3028,Created_tag_3028,AR,DWORD
1029,Server_1,Tag_30,3029,Created_tag_3029,AR,DWORD
1030,Server_1,Tag_31,3030,Created_tag_3030,AR,REAL

最佳答案

我确信有一个重复项,您是根据指针的大小而不是所指向的对象来分配第二个缓冲区:

/* Allocate memory for each underlying server tag information */
ua_server[NUM_OF_UNDERLYING_SERVER].underlying_server_data =
      malloc(tags_count * sizeof(ua_server->underlying_server_data));

变成:

/* Allocate memory for each underlying server tag information */
ua_server[NUM_OF_UNDERLYING_SERVER].underlying_server_data =
      malloc(tags_count * sizeof(*(ua_server->underlying_server_data)));

请注意,实际代码 *(ua_server->underlying_server_data 目前很糟糕,但 sizeof 是编译时的,只是使用代码作为模板来获取对象大小。

我有时希望有一个编译器警告“您询问了指针的大小”

关于c - 由于字符串复制导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56021222/

相关文章:

c - 在 C 中向 char *[] 添加单词

c - SOCK_SEQPACKET Unix 套接字上的空数据包

javascript - 从 Ajax 传递时数组值变为 null

java - 如何通过 "java.lang.String"解决 java.lang.OutOfMemoryError 错误,由 "<system class loader>"Eclipse 内存分析器加载

java - String.replaceAll()方法: how to make sure processed characters can never be replaced again

python - 在 python 中打印字符串中的一个单词

c - 缓冲区溢出 - 局部变量在堆栈上的顺序

c - 如何找到质数

python - 沿 numpy 数组轴的 k-最小值的索引

arrays - 如何在 bash 中连接数组?