由strcat函数引发的C语言中数组和指针问题的思考

问题一

首先,来看一下下面这段代码:

#include <stdio.h>
#include <string.h>
int main() {
    char *str = "media";
    char *tmp = "aaa";
    printf("str: %s\n",str);
    strcat(str,tmp);
    printf("str: %s\n",str);
    return 0;
}

代码打眼儿一看,功能很明显:把str指针指向的字符串和tmp指针指向的字符串连接起来再赋给str指向的字符串。我们把这个程序运行一下,如下图:

报出了段错误,使用cgdb调试一下,发现问题是出在strcat函数处:

感觉很奇怪,就去查找了strcat函数的一些示例,发现几乎所有的strcat的示例都是连接的两个数组类型字符串或者一个数组类型一个指针类型(指针类型指向的字符串一定是接在数组字符串之后)。自己手动测试了一下,把*str改为了str[20],发现程序成功运行:

后经过一系列的文档查阅,得知定义为指针所指向的字符串是常量字符串,只能读取不能写入。要连接这样的字符串,得另外开辟一个空间存放连接起来的字符串。如果非要将两个变量定义为指针类型,可以把程序修改为以下形式:

#include <stdio.h>
#include <string.h>
int main() {
    char *str = "media";
    char *tmp = "aaa";
    char *res = (char *)malloc(strlen(str)+strlen(tmp)+1);
    printf("str: %s\n",str);
    strcat(strcpy(res,str),tmp);
    printf("str: %s\n",res);
    return 0;
}

得到的结果正确:

问题二

原文地址:https://www.cnblogs.com/intoxication/p/10780207.html

时间: 2024-08-28 14:39:56

由strcat函数引发的C语言中数组和指针问题的思考的相关文章

C语言中数组与指针

数组是内存空间的一片连续的区域,用于存贮一组相同数据类型元素的集合. 指针变量中存放的是变量的地址,通过指针取得地址,再通过地址提取数据. 在大多是C语言书中,都有这样的说法,“数组和指针是相同的”.其实,数组与指针,只能在特定的情况下才是相同的,在大多书情况下,他们并不相同. C语言中每个表示变量的符号都代表一个地址,而每个变量的值就是该地址里所存储的内容. 定义一个字符数组 char a[]="asdfghjkl";现在来访问第i个字符a[i],编译器符号表中具有一个符号,它代表的

c语言中数组,指针数组,数组指针,二维数组指针

1.数组和指针 int array[5] = {1,2,3,4,5};// 定义数组 // 1. 指针和数组的关系 int * pa = array; pa = array; // p[0] == *(p+0) == array[0] == *(array+0) printf("%p\n", pa); printf("%p\n", array); /* 访问数组两种方式 1. 下标法访问 数组名[下标] 指针[下标] 下标:偏移量 2. 指针法访问 *(p+1) *

C 语言中有趣第指针操作(转)

http://blog.csdn.net/ghevinn/article/details/37651149(反汇编题目需要分析) 4.取出内存区域的值 在取某内存地址开始的一个区域的值的时候,取出的值取决于用来取值的类型,譬如int为4个byte,char为1个byte,程序如: void main(){ int a[2] = {261,0}; int *pi = a; char *p = (char*)pi; cout << *(int *)p++ << endl;  //取出p

对于C语言中数组名是指针的理解

我们都知道,c语言中数组名是一个指针,比如下面这段代码 #include<iostream>using namespace std;int main(){ int a[4]={1,2,3,4}; for(int i=0;i<4;i++) {  cout<<*(a+i);//*(a+i)和a[i]是等价的.  cout<<endl; } return 0;} 但是看下面这个代码 #include<iostream>using namespace std;

c语言中结构体指针

1.指向结构体的指针变量: C 语言中->是一个整体,它是用于指向结构体,假设我们在程序中定义了一个结构体,然后声明一个指针变量指向这个结构体,那么我们要用指针取出结构体中的数据,就要用到指向运算符"->". 举例说明: struct SunLL { int a; int b; int c; }; struct SunLL  * p;               //定义结构体指针 struct SunLL A = {1,2,3};    //定义一个SunLL类型的变量A

C++语言中数组指针和指针数组彻底分析

#################################                              ##       基本知识               ##                              ################################# 当然我们一切都是从最简单的内建类型开始,最后我会做一些推广.先看一下基本的形式,我们从这里起步! Cpp代码 --------------指针---------------- int a

C语言中的二级指针(双指针)

原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/7220688 C语言更多查看 C语言使用注意事项(一) C语言使用注意事项(二) C语言使用注意事项(三) 二级指针又叫双指针.C语言中不存在引用,所以当你试图改变一个指针的值的时候必须使用二级指针.C++中可以使用引用类型来实现. 下面讲解C中的二级指针的使用方法. 例如我们使用指针来交换两个整型变量的值. 错误代码如下: 一级指针 [cpp] view plaincopyp

c语言中数组名的本质

c语言中的数组名的本质是什么,数组名是指针吗? 1.数组名是数组元素的首地址#include <stdlib.h>#include <stdio.h>void main() { int a[10] = {1, 2, 3, 4, 5, 6, 7, 8,9, 10}; printf("a:%d &a:%d :%d \n", a, &a); system("pause"); }上面的程序中,a &a大小一样,证明a就是数组元

c语言中数组名和指针变量的区别

编译器工作原理:在64位的计算机中,当创建一个指针变量时,计算机会为它分配8个字节的存储空间.但如果创建的是数组呢?计算机会为数组分配存储空间,但不会为数组变量分配任何空间,编译器仅在出现它的地方把它替换成数组的起始地址. 结论1:由于计算机没有为数组变量分配空间,也就不能把它指向其他地方.例题: char s[]="How big is it?"; char *t=s; //正确,将数组的地址赋给指针变量t s=t; //错误,数组变量没有存储空间,无法存储指针变量t的值,编译报错