* char数组末尾的分段错误

时间:2016-10-20 15:53:33

标签: c arrays linux segmentation-fault memory-segmentation

我很高兴使用C和我遇到问题。我想使用以下代码将linux命令行(类似date | ./date_split)中的字符串输入拆分为一个数组,稍后我将访问和修改它。分裂工作最初,但最后我得到一个分段错误。谁能解释我做错了什么?

int main()
{
   char *indate[10];
   int i= 1;
   char str[100][50];
   fgets(&str [0], 50, stdin);
   const char s[2] = " ";
   char *token;

  /* get the first token */
  token = strtok(str, s);
  indate[i] = malloc(strlen(token)+1);
  strcpy(indate[i], token);
  printf( "Array before: %s\n", indate[i]);     

 /* walk through other tokens */
 while( token != NULL )
{
  printf( "Token before: %s\n", token );

  token = strtok(NULL, s);
  indate[i] = malloc(strlen(token)+1);
  strcpy(indate[i], token);

printf( "Token2 After: %s\n", token );
printf( "Array2 After: %s\n", indate[i]);     
i++;   
}

    return(0);
}

提供终端输出:

Array before: Thu
Token before: Thu
Token2 After: 20
Array2 After: 20
Token before: 20
Token2 After: Oct
Array2 After: Oct
Token before: Oct
Token2 After: 11:37:56
Array2 After: 11:37:56
Token before: 11:37:56
Token2 After: EDT
Array2 After: EDT
Token before: EDT
Token2 After: 2016

Array2 After: 2016

Token before: 2016

Segmentation fault (core dumped)

2 个答案:

答案 0 :(得分:2)

您的程序问题:您对日期组件的索引i,从1开始而不是0(为此目的是一个可怕的变量名称)并且不会一致地更新(第一个条目被覆盖) ); str()数组是一个完全混乱的分配(例如两个维度,只使用一个);你假设第一个strtok()成功,但输入不好可能不是这样;在您已经使用过结果之前,您不会测试后续strtok()次来电是否成功;你没有尝试free() malloc()记忆#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXIMUM_TOKENS 16 #define MAXIMUM_TOKEN_LENGTH 32 const char *separator = " "; int main() { char string[(MAXIMUM_TOKEN_LENGTH + strlen(separator)) * MAXIMUM_TOKENS + 1]; // estimate char *result = fgets(string, sizeof(string), stdin); if (result == NULL) { fprintf(stderr, "An appropriate error message goes here.\n"); return EXIT_FAILURE; } /* strip final newline (\n) if present */ size_t last_index = strlen(string) - 1; if (string[last_index] == '\n') { string[last_index] = '\0'; } /* get the first token */ char *token = strtok(string, separator); char *date_parts[MAXIMUM_TOKENS]; int date_parts_index = 0; /* walk through other tokens */ while (token != NULL) { date_parts[date_parts_index++] = strdup(token); token = strtok(NULL, separator); } /* print the tokens and free the strdup/malloc memory */ for (int i = 0; i < date_parts_index; i++) { (void) puts(date_parts[i]); free(date_parts[i]); } return EXIT_SUCCESS; } ,甚至不记得某些记忆。

下面是对原始代码的修改,还会添加一些错误检查和其他细节:

% date | ./a.out
Thu
Oct
20
09:58:00
PDT
2016
% 

<强> USAGE

strtok()

虽然这是strsep()的恰当用法,但要小心。它是较早时代的工件,应该避免使用更安全,更现代的库函数,如strtok_r()SELECT MAX( ticket_finish ) over () AS cutOff, ticket_price, ticket_id, ticket_name, ticket_qty, ticket_start, ticket_finish, ticket_max, ticket_type_no, ticket_min, ticket_order, ticket_fee FROM ticket WHERE ticket_event_no = :id AND ticket_hide = 0

答案 1 :(得分:1)

来自strtok()手册

  

返回值          strtok()和strtok_r()函数返回指向下一个的指针          令牌,如果没有更多令牌,则为NULL。

一旦没有更多令牌,public static zoomInMap(times: number): Promise<void> { return Promise.all(new Array(times).fill().map(() => { let zoomInButton = element(by.css('#main > cc-map > div.google-map-base-container-inner > div > div.gmnoprint.gm-bundled-control.gm-bundled-control-on-bottom > div:nth-child(1) > div > div:nth-child(1)')); zoomInButton.click(); return browser.sleep(Config.ZOOM_ANIMATION_TIMEOUT).then(() => { // console.log('Map Zoomed In'); }); })); } 包含一个NULL指针,因此token段错误。见strlen not checking for NULL