关于C语言函数strtok引发的思考
来源:互联网 发布:鼻行动物存在吗 知乎 编辑:程序博客网 时间:2024/05/17 22:39
欢迎参与讨论,转载请注明出处。
前言
近期遇到个C语言的课题作业,要求完成parse功能(以空格、回车、TAB为分割符分割字符串,输出结果且返回数组。)该功能涉及到strtok函数的一些问题,特此开贴记录。
详解
以下为程序源码:
#include <stdio.h>#include <string.h>#include <stdlib.h>struct ListNode { char * value; struct ListNode * next;};char ** parse(char * line) { if (line == NULL) { return NULL; } static char delim[] = " \t\n"; /* SPACE or TAB or NL */ int count = 0; char * token; char ** newArgv; char str[strlen(line)]; strcpy(str, line); token = strtok(str, delim); if (token == NULL) { return NULL; } struct ListNode * head = (struct ListNode *)malloc(sizeof(struct ListNode)); struct ListNode * cur = head; cur->value = token; count ++; while (1) { token = strtok(NULL, delim); if (token == NULL) { break; } cur->next = (struct ListNode *)malloc(sizeof(struct ListNode)); cur = cur->next; cur->value = token; count ++; } newArgv = (char **)malloc((count + 1) * sizeof(char *)); cur = head; for (int i = 0; i < count; i++) { newArgv[i] = (char *)malloc(strlen(cur->value) * sizeof(char)); strcpy(newArgv[i], cur->value); printf("[%d] : %s\n", i, cur->value); free(cur); cur = cur->next; } newArgv[count] = NULL; //tail return newArgv;}int main() { char ** argv = parse("system program"); return 0;}
第一个问题
首先第一个问题便是这里:
char str[strlen(line)]; strcpy(str, line); token = strtok(str, delim);
最初尝试直接把parse函数的参数line直接作为strtok函数的第一参数填入,结果不行。查阅文档后发现strtok的声明为:
//param: str -- 要被分解成一组小字符串的字符串。 //param: delim -- 包含分隔符的 C 字符串。 //return: 该函数返回被分解的最后一个子字符串,如果没有可检索的字符串,则返回一个空指针。 char *strtok(char * str, const char * delim);
可以发现,第一参数char * str要求的并非const,而我在调用时填入的参数为‘system program’,这种字符串数据是作为‘const char[]’保存在字符串常量区的,故不符合参数需求。需要重新申请一片栈空间复制line的内容再作为参数填入。
第二个问题
由此衍生的第二个问题便是:为何要为newArgv[i]申请新的空间,而非newArgv[i] = cur->value;
?
newArgv[i] = (char *)malloc(strlen(cur->value) * sizeof(char)); strcpy(newArgv[i], cur->value);
这一点的原因主要是 strtok返回的字符串其实并非新的副本,而是从str上截取的一部分而已。 而cur->value便是来自于str,且str是拥有生命周期的栈数据,而如果将这样的部分保存在newArgv后返回到外部,便会因为生命周期问题,导致数据被回收。这将会产生很可怕的后果。所以必须申请新的空间,形成复制。
后记
没有垃圾回收的C/C++,编程时必须对内存的分配和流向必须要有十分清晰的认识,不然就很容易发生内存泄漏和野指针现象。慎之、慎之。
阅读全文
0 0
- 关于C语言函数strtok引发的思考
- C语言strtok函数
- c语言:strtok()函数
- C语言函数strtok
- 关于C语言字符串函数的思考
- 关于C语言字符串函数的思考
- C语言strtok函数的用法
- C语言strtok函数的用法
- C语言sizeof引发的思考
- C语言除0引发的思考
- C语言之strtok函数
- c语言strtok函数用法
- C语言:strtok函数小结
- C语言 strtok函数使用
- C语言 strtok函数使用
- 程序基础关于C语言字符串函数的思考
- 关于C语言中free函数的一点思考
- c语言的split字符串分割函数strtok的使用
- DSPF28335学习笔记
- 在IDEA中使用 Spring Initializr 新建 spring boots 项目
- 按自然班优先分组算法
- 由于CentOS的系统安装了epel-release-latest-7.noarch.rpm 导致在使用yum命令时出现Error: xz compression not available问题
- Distributed Transaction Patterns
- 关于C语言函数strtok引发的思考
- 线程池中DefaultThreadFactory类
- Android StudioRe-download dependencies and sync project (requires network)问题
- leetcode 20. Valid Parentheses
- java静态代码块/静态属性、构造块、构造方法执行、main方法、普通代码块的顺序
- 从开发到部署会用到的 Docker 命令
- Kafka 之 入门
- iconfont图标
- 深度学习第八章自学笔记——深度模型中的优化