热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

strtok-字符数组与字符指针[重复]-strtok-chararrayversuscharpointer[duplicate]

PossibleDuplicate:strtokwontaccept:char*str可能的副本:strtok不能接受:char*strWhenusingthe

Possible Duplicate:
strtok wont accept: char *str

可能的副本:strtok不能接受:char *str

When using the strtok function, using a char * instead of a char [] results in a segmentation fault.

使用strtok函数时,使用char *而不是char[]会导致分割错误。

This runs properly:

这个正常运行:

char string[] = "hello world";
char *result = strtok(string, " ");

This causes a segmentation fault:

这会导致分割错误:

char *string = "hello world";
char *result = strtok(string, " ");

Can anyone explain what causes this difference in behaviour?

谁能解释这种行为差异的原因吗?

6 个解决方案

#1


26  

char string[] = "hello world";

This line initializes string to be a big-enough array of characters (in this case char[12]). It copies those characters into your local array as though you had written out

这一行将字符串初始化为足够大的字符数组(在本例中为char[12])。它将这些字符复制到本地数组中,就像您编写的那样

char string[] = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0' };

The other line:

其他线:

char* string = "hello world";

does not initialize a local array, it just initializes a local pointer. The compiler is allowed to set it to a pointer to an array which you're not allowed to change, as though the code were

不初始化一个本地数组,它只是初始化一个本地指针。编译器可以将它设置为指向数组的指针,而不允许对数组进行修改,就像代码一样

const char literal_string[] = "hello world";
char* string = (char*) literal_string;

The reason C allows this without a cast is mainly to let ancient code continue compiling. You should pretend that the type of a string literal in your source code is const char[], which can convert to const char*, but never convert it to a char*.

C之所以允许这样的原因,主要是为了让古老的代码继续编译。您应该假定您的源代码中的字符串文字的类型是const char[],它可以转换为const char*,但永远不要将它转换为char*。

#2


11  

In the second example:

在第二个例子中:

char *string = "hello world";
char *result = strtok(string, " ");

the pointer string is pointing to a string literal, which cannot be modified (as strtok() would like to do).

指针字符串指向字符串文字,不能修改它(就像strtok()想做的那样)。

You could do something along the lines of:

你可以做一些类似的事情:

char *string = strdup("hello world");
char *result = strtok(string, " ");

so that string is pointing to a modifiable copy of the literal.

这个字符串指向文字的可修改拷贝。

#3


4  

strtok modifies the string you pass to it (or tries to anyway). In your first code, you're passing the address of an array that's been initialized to a particular value -- but since it's a normal array of char, modifying it is allowed.

strtok修改您传递给它的字符串(或者尝试使用它)。在您的第一个代码中,您传递的是一个被初始化为特定值的数组的地址——但是由于它是一个正常的char数组,所以可以修改它。

In the second code, you're passing the address of a string literal. Attempting to modify a string literal gives undefined behavior.

在第二段代码中,传递字符串文字的地址。尝试修改字符串文字会产生未定义的行为。

#4


3  

In the second case (char *), the string is in read-only memory. The correct type of string constants is const char *, and if you used that type to declare the variable you would get warned by the compiler when you tried to modify it. For historical reasons, you're allowed to use string constants to initialize variables of type char * even though they can't be modified. (Some compilers let you turn this historic license off, e.g. with gcc's -Wwrite-strings.)

在第二种情况(char *)中,字符串位于只读内存中。字符串常量的正确类型是const char *,如果您使用该类型声明变量,那么当您试图修改它时,编译器将警告您。出于历史原因,您可以使用字符串常量来初始化类型char *的变量,即使它们不能被修改。(一些编译器允许您关闭这个历史许可证,例如使用gcc的-Wwrite-strings。)

#5


0  

The first case creates a (non const) char array that is big enough to hold the string and initializes it with the contents of the string. The second case creates a char pointer and initializes it to point at the string literal, which is probably stored in read only memory.

第一个案例创建了一个(非const) char数组,它足够大,可以容纳字符串并使用字符串的内容初始化它。第二种情况创建一个char指针并初始化它到指向字符串文字,它可能存储在只读内存中。

Since strtok wants to modify the memory pointed at by the argument you pass it, the latter case causes undefined behavior (you're passing in a pointer that points at a (const) string literal), so its unsuprising that it crashes

由于strtok希望修改您传递它的参数所指向的内存,所以后一种情况会导致未定义的行为(您正在传递指向(const)字符串文字的指针),因此它不会意外地导致它崩溃

#6


0  

Because the second one declares a pointer (that can change) to a constant string...

因为第二个声明一个指针(可以改变)到一个常量字符串……

So depending on your compiler / platform / OS / memory map... the "hello world" string will be stored as a constant (in an embedded system, it may be stored in ROM) and trying to modify it will cause that error.

所以取决于你的编译器/平台/操作系统/内存映射…“hello world”字符串将作为常量存储(在嵌入式系统中,它可能存储在ROM中),并试图修改它将导致错误。


推荐阅读
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
author-avatar
路边一烧饼
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有