指针和字符串和字符串常量、用gdb来获取非法内存中的信息

例程1

#include<stdio.h>
int main(void)
{
    char *s="hello";
    printf("%s\n", s);
    s[0]="H"
    //因为s指针指向的字符串"hello"是字符串常量,所以不能通过指针进行更改,所以这里会产生段错误
    printf("%s\n", s);
    return 0;
}

例程2

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void)
{
    char *s = (char *)malloc(6*sizeof(char));
    strcpy(s,"hello");
    printf("%s\n", s);
    s[0] = ‘H‘;
    //因为为s分配了动态内存,所以更改可以通过s指针进行更改
    printf("%s\n", s);
    return 0;
}

例程3
字符串开始位置没有规定,但是规定必须以‘\0‘作为结尾标识符

int main(void)
{
    char *s="hello";
    printf("%s\n", s);
    //打印出hello
    printf("%s\n", &s[1]);
    //打印出ello
    printf("%s\n", &s[1]);
    //打印出llo

    //...

    printf("%s\n", &s[4]);
    //打印出o

    return 0;
}

假设例程3命名为string.c
    用命令gcc -g -o string string来编译程序
    再用gdb ./string来调试程序
        break main
        run
        next
        next
        print s
        //显示结果$1 = 0x40061c "hello"
        print s+1
        //显示结果$2 = 0x40061d "ello"
        print s[1]
        //显示结果$3= 0x40061d ‘e‘
        //注意区别 print s+1 与print s[1]的差异,其中print s+1等价于 print &s[1]
        //上面3条print命令都是访问string程序中合法的内存区域
        print s+10
        //显示的结果可能是$4 = 0x400626 "\003;("
        //这条·print语句其实是去访问了在string中非法的内存区域(越界访问),但是通过gdb来访问也是可以获取相关信息的,有时候可以这样通过gdb来来获取某块以前使用过现在不合法但是可能有一些有用的信息的内存来获取一些有用信息

时间: 2024-10-11 11:16:37

指针和字符串和字符串常量、用gdb来获取非法内存中的信息的相关文章

windows下查看C语言字符数组(俗称:字符串)在内存中地址信息的操作过程

#include <stdio.h> #pragma warning(disable:4996) int power10(int n) { if (n == 0) { return 1; } int val = 10; for (int i = 1; i < n; i++) { val *= 10; } return val; } 在开发平台vs2013下面,选择调试->窗口->内存->内存1 1 int main(int arg, char *args[]) 2 {

黑马程序员-C语言基础:指针类型与指针和数组、字符串的关系

//指针变量就是用来存储地址的,只能存储地址 格式:  int  *p;  这个p为指针变量:指针变量占8个字节 类型是用来说明这个指针指向的类型: 比如上边的int代表这个指针变量会指向int类型的存储空间: int *p = &a;//这样一句可以写,此时的*只是一个标志,表示这个*只是表示p是个指针: *p = &a;//这样写就错了:此时*p表示取p指向的空间的值: 指针疑问:指针既然都占据8个字节,那么为什么要划分类型, 是因为当用*p指针取值或者赋值的时候,知道该取几个字节,比

黑马程序员---C基础10【数组指针】【指针数组】【字符串指针】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- [数组指针] 1.数组指针: 定义一个指针指向数组的某一个元素 数组元素指针:指针变量可以指向数组元素: 1)数组名a不代表整个数组,只代表数组首元素的地址: 2)是指向首地址,而不是每一个元素:  2.数组指针的引用: 在指针向数组元素时,允许以下操作 加一个整数(用+或+=),如p+1: 减一个整数(用-或-=),如p-1: 自加P++ 自减p--; 两个指针相减:p1-p2: P+1指向

Swift3.0语言教程使用指针创建和初始化字符串

Swift3.0语言教程使用指针创建和初始化字符串 Swift3.0语言教程使用指针创建和初始化字符串苹果的Swift团队花了不少功夫来支持C的一些基础特性.C语言中为我们提供了指针,Swift也不例外,开发者可以使用指针去创建和初始化字符串. (1)在NSString中init(bytes:length:encoding:)方法可以从给定字符串按照指定获取方向,得到指定个数的字符,然后使用这些字符创建和初始化字符串.其语法形式如下: convenience init?(bytes: Unsaf

string字符串常量池在内存中的位置

这里仅仅是举个简单的样例说明字符串常量池在内存中的位置. 闲言少叙,直接上代码. Java代码   <span style="font-size: large;">import java.util.ArrayList; public class Test { public static void main(String[] args) { String str = "abc"; char[] array = {'a', 'b', 'c'}; String

C++内存问题大集合(指针问题,以及字符串拷贝问题,确实挺危险的)

作者:rendao.org,版权声明,转载必须征得同意. 内存越界,变量被篡改 memset时长度参数超出了数组长度,但memset当时并不会报错,而是操作了不应该操作的内存,导致变量被无端篡改 还可能导致内存越界的函数有memset.memcpy.memmove.strcpy.strncpy.strcat.sprintf等等 临时指针问题,std::string.wstring的c_str()是个临时指针 c_str()返回值是个char*/wchar_t*指针,这个数组的数据是临时的,当有一

指针与数组、字符串

通过指针我们可以访问内存中任意地址,那么自然可以访问数组,因为数组在内存中占据了一段连续的空间,那么如何实现的呢? 1 #include<stdio.h> 2 3 int main(){ 4 //定义一个整型数组 5 int array[4] = {7,15,3,9}; 6 //定义一个整型的指针 7 int *p; 8 //将数组的首元素地址赋值给指针p 9 p = &array[0]; 10 //打印出指针所指内存单元的值 11 printf("指针所指内存单元的值为%d

字符串与字符串函数

定义字符串的方法:1.字符串常量2.char数组 //这种方法数组名会看作首元素的地址的同义词,不可用++,增量运算符只能用于变量名前. 2.可以用*(head+1)这种格式 3.数组元素是变量,数组名是地址常量3.cahr指针 //是一个指针,是变量4.字符串数组 举例:char character[23]= "fsdfdsf" "sdfdf";这是可以的 //把字符串看作指针#include<stdio.h>int main(void){ print

关于Delphi中的字符串的浅析(瓢虫大作,里面有内存错误的举例)

关于Delphi中的字符串的浅析 只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(Short String) 长字符串(Long String) 宽字符串(Wide String) 零结尾字符串(Null-Terminated String).PChar和字符数组 1.短字符串(Short String) 固定长度,最大字符数个数为255,短字符串也成为长度字节(Length-byte)字