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

关于字符串指针动态分配内存和赋初值(初学者求教)

我被string,char,char*,char[],弄到思维乱七八糟了,望各位大大帮我整理下思维--!chara[]abc;自动分配4个内存(包含0)的字符串数
我被string,char,char*,char[],弄到思维乱七八糟了,望各位大大帮我整理下思维- -! 


char a[] = "abc";//自动分配4个内存(包含'/0')的字符串数组;
char *cpa = a;//指向数组a的首地址
【问题1:cpa指针已经分配空间给他了?没有new空间给他哦?】
char *cpb = new char[100];//为cpb分配100个字符大小的空间
cpb = a; //把cpb指向数组a的首地址
【问题2:这种方法和上面的方法有什么区别啊?是不是这里分配了100个字符大小的空间给指针,但指针每次指向一个字符,所以是在浪费空间?】
cout< 【问题3:我知道*cpb是输出当前指针所指向地址的值'a',但输出cpb指针的结果是整个字符串abc,cpb是一个字符指针,指向一个字符串,怎么会输出整个字符串而不是一个字符呢?难道系统自动做了遍历?】

char *cpc = "def";//cpc指针指向字符串首地址
【问题4:和问题1类似,这指针已经分配空间给他了?】

string b;
b = cpc;
【问题5:估计这个关于STL里面的string,用sring 定义了一个字符串常量b(而非指针)怎么可以把一个字符指针cpc赋值给字符串常量b的?】

【问题6: char *p = "abc"   对比   char e[] = "abc";  char *p = e;的区别】
个人猜想: 前者没为字符串申请空间,所以不能改动指针所指向的值,而后者所分配的空间则为4个字符大小的空间,所以只能删减字符而不能增加字符。

最后一个问题- -!!这就是实际操作中遇到的问题。
const char *a = 【调用一个函数,其返回值为("const char *x")】; //获取一段字符串
编译没错,但调试跟踪数据时,却说“错误的指针”,后来发现是因为指针a没有初始化和分配内存空间。
我随便写了个简单的相似的例子
const char *m = "poi";
const char *n = m;
cout< 为什么这样子又不用申请空间就直接可以运行呢?

我思路很乱,问题很多,望各位热心人士帮忙解答



13 个解决方案

#1



char a[] = "abc";//自动分配4个内存(包含'/0')的字符串数组;
char *cpa = a;//指向数组a的首地址
【问题1:cpa指针已经分配空间给他了?没有new空间给他哦?】

答:指针一定要分配空间才能用吗?不是。难道是老谭的书这么说的吗?怎么这么多人有这个想法。
只要用有效的指针来初始化或者赋值给他后就可以访问。char*cpa = a;//这句的意思是用数组a的首元素的指针来初始化cpa;


#2


char *cpc = "def";//cpc指针指向字符串首地址
【问题4:和问题1类似,这指针已经分配空间给他了?】

应该写成 
const char *cpc = "def";  //没有分配空间, cpc 指向了字符串常量

#3


算了不说了,楼主看C++PRIMER吧,不要看哪些乱七八糟的书。否则像这种莫明奇妙的问题只会不断的冒出来。。

#4


数组和指针

#5


const char *m = "poi";  // 没有分配空间,指向了字符串常量
const char *n = m;      // 没有分配空间,指向了字符串常量
cout<

#6


#include 
#include 
#include 
using namespace std;
char* cfun(char* str)
{
    char* ret = str;
    /*  函数功能实现
        str是个指针,会在操作中改变地址,
        所以增加个ret指针返回地址用*/
    str++;  // str 可以改变地址
    return ret;
}
const char* cfun1(const char* str)
{
    str = strstr(str, "world"); // str指针改变地址,但没有修改传入的字符
    return str;
}
string& strfun(string& str)
{
    /* 函数功能实现
       str是引用的,不会改变地址
    */
//  str++;  // 错误: no 'operator++(int)'
    return str;
}

int main()
{
    char cstr[] = "Hello world!";
    string str("Hello world!");

    cout << cfun(cstr) << endl;
    cout << cfun1("Hello world!") << endl;
    cout << strfun(str) << endl;
    return 0;
}

看代码,看贴图, 不修改,不能修改 就用 const

#7


那只是指针指向某一个地址,并没有真正的为指针分配内存空间

#8


引用 1 楼 mingliang1212 的回复:
char a[] = "abc";//自动分配4个内存(包含'/0')的字符串数组;
char *cpa = a;//指向数组a的首地址
【问题1:cpa指针已经分配空间给他了?没有new空间给他哦?】

答:指针一定要分配空间才能用吗?不是。难道是老谭的书这么说的吗?怎么这么多人有这个想法。
只要用有效的指针来初始化或者赋值给他后就可以访问。char*cpa = a;//这句的意思是用……


看来上面的大神们的解答,主要原因在于,定义指针不一定要为其分配空间,但这样的指针不能修改其值,所以最好在指针前加上“const”。
这样说对吧???
那么什么时候才需要对指针new一个内存空间,函数指针的运用时???


还有,各位大神能回答一下最后一个问题么?

const char *a = 【调用一个函数,其返回值为("const char *x")】; //获取一段字符串
编译没错,但调试跟踪数据时,却说“错误的指针”,后来发现是因为指针a没有初始化和分配内存空间。
为什么要初始化和分配内存空间

#9


引用 1 楼 mingliang1212 的回复:
char a[] = "abc";//自动分配4个内存(包含'/0')的字符串数组;
char *cpa = a;//指向数组a的首地址
【问题1:cpa指针已经分配空间给他了?没有new空间给他哦?】

答:指针一定要分配空间才能用吗?不是。难道是老谭的书这么说的吗?怎么这么多人有这个想法。
只要用有效的指针来初始化或者赋值给他后就可以访问。char*cpa = a;//这句的意思是用……


又有新的理解- -! char *cpa = a; 也有分配空间的,只是常量不能修改而已。
const char *a = 【调用一个函数,其返回值为("const char *x")】; 
至于最后的问题也知道原因了,因为作为赋值的是一个函数的返回值,该返回值在完成操作后就会释放掉他的内存空间,那么如果不初始化指针a的话,那么a将会指向一个被释放掉的控制,所以会发生指针出错的问题。

#10


首先你要彻底忘掉要给指针分配空间这件事再看下面的内容。

指针作为一个普通的对象。他的内存管理和普通对象一模一样,不用额外的分配空间给他。
指针可以指向一个与指针类型相应的类型的对象,而他的值就是这个对象地址。

访问一个并不是指向一个有效对象的指针是不合法的。//通过赋值或初始化使指针指向一个有效的对象。

const char*p; 代表p指向的对象是 const char类型。所以指向的对象不可以被更改。

char* 类型可以转换成 const char*,反之不。

数组名可以转换成其首元素的指针:
const char *m = "poi";//“poi”是一个匿名的字符类型数组,可以转化成其首元素的指针。。

详见4楼链接的大神讲解。

#11


new的作用是在堆内存中获得内存,并构造一个匿名的左值对象,并返回他的指针。

给指针赋值或初始化的不一定是new,可以是任何相应的类型的表达式。所以完全不存在分配内存一说。

#12


不要纠结,看看汇编一切都会明朗的~

#13


这个看看吧

推荐阅读
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
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社区 版权所有