100条经典C语言笔试题 不明白的地方

时间:2021-06-19 19:43:19
我做100条经典C语言笔试题
6, int main()
{
    char a;
    char *str=&a;
    strcpy(str,"hello");
    printf(str);
    return 0;
}

答案强调“因为越界进行内在读写而导致程序崩溃” 我想问一句什么是“内在读写”?这个程序越界越了什么界线?

26 个解决方案

#1


内存读写 100条经典C语言笔试题 不明白的地方

#2


1,没有为str分配内存空间,将会发生异常。
2,将一个字符串复制进一个字符变量指针所指地址。
字符型变量在32位机中只占1个字节,而字符串即使空也有占1个字节了,必须越界

#3



    char a;  //系统分配了一个字节给a
    char *str=&a; // 把a的地址给 str, 也就是str可用字节只有一个
    strcpy(str,"hello"); // 这里你“hello” 赋值到一个字节内存的 显然会内存出错的
    printf(str);
    return 0;

#4


指针可用空间不够

#5


指向的内存空间不够用呗

#6


"hello"有6个字节,而str指向占1个字节的内存空间,然后把6个字节的内容拷给一个字节的空间,你说越界不越界。

#7


说的不错,受教啦

#8



//首先,LZ应该明白越界,你申请了一个字节的空间,这个一个字节就是你自己定义的界限,
//然后你写了6个字节,那你就是越过你自己定义的界限了.
//函数堆栈中,变量之后的堆栈通常保存着函数返回的信息,你写越界了,也就破坏了那些信息,
//造成函数可能无法返回,程序就崩溃了。这也叫函数栈溢出。
int main()
{
    char a;//申请了一个字节的空间
    char *str=&a;
    strcpy(str,"hello");//写了6个字节的空间
    printf(str);
    return 0;
}

#9


引用 5 楼 qzf362269994 的回复:
指向的内存空间不够用呗
不是,是str这个指针不能去修改指向的内存的内容。。。如果想修改可以定义为char str[]的形式就可以了。试图去修改char *str。会出现内存出错。程序崩溃

#10


好吧,学习了。

#11



malloc 和 free

#12


综上所述,楼主明白了吧

#13



int main()
{
    char a;   //一个字节的空间
    char *str=&a;   //指向一个字节的空间
    strcpy(str,"hello");   //在一个字节的空间中放6个字节“hello”5个字母,加一个结束符
    printf(str);   //输出一个字节的空间中的内容。
    return 0;
}

#14


注意,str指向的空间大小是不确定的

#15


该回复于2013-07-31 08:43:29被管理员删除

#16


 int main()
 {

     char buf1[10];//在a前面留出10字节
     char a;
     char buf2[10];//在a后面留出10字节
     char *str=&a;
     strcpy(str,"hello");//hello和后面的'\0'隐含覆盖了a开始的6个字节
     printf(str);
     return 0;
 }

#17


引用 6 楼 dnvycumt3 的回复:
"hello"有6个字节,而str指向占1个字节的内存空间,然后把6个字节的内容拷给一个字节的空间,你说越界不越界。

hello是六个字节?真的假的?我刚学C,不知道是不是有什么厉害的东西。。。

#18


引用 17 楼 jssd64 的回复:
Quote: 引用 6 楼 dnvycumt3 的回复:

"hello"有6个字节,而str指向占1个字节的内存空间,然后把6个字节的内容拷给一个字节的空间,你说越界不越界。

hello是六个字节?真的假的?我刚学C,不知道是不是有什么厉害的东西。。。

"hello"后面有个结束符'\0'你看不到而已,按照惯例  上一段代码:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char str[] = "hello";
printf("%d\n", sizeof(str));//结果是6  
system("pause");
}

#19


同意三楼的 100条经典C语言笔试题 不明白的地方

#20


引用 16 楼 zhao4zhong1 的回复:
 int main()
 {

     char buf1[10];//在a前面留出10字节
     char a;
     char buf2[10];//在a后面留出10字节
     char *str=&a;
     strcpy(str,"hello");//hello和后面的'\0'隐含覆盖了a开始的6个字节
     printf(str);
     return 0;
 }
100条经典C语言笔试题 不明白的地方不一定是 一前一后的 

#21


100条经典C语言笔试题 不明白的地方

#22


100条经典C语言笔试题 不明白的地方

#23


100条经典C语言笔试题 不明白的地方

#24


1:    #include <string.h>
2:    #include <stdio.h>
3:    int main()
4:    {
00401000 55                   push        ebp
00401001 8B EC                mov         ebp,esp
00401003 83 EC 60             sub         esp,60h
00401006 53                   push        ebx
00401007 56                   push        esi
00401008 57                   push        edi
5:
6:         char buf1[10]="111111111";//在a前面留出10字节
00401009 A1 B8 20 40 00       mov         eax,[string "111111111" (004020b8)]
0040100E 89 45 F4             mov         dword ptr [ebp-0Ch],eax
00401011 8B 0D BC 20 40 00    mov         ecx,dword ptr [string "111111111"+4 (004020bc)]
00401017 89 4D F8             mov         dword ptr [ebp-8],ecx
0040101A 66 8B 15 C0 20 40 00 mov         dx,word ptr [string "111111111"+8 (004020c0)]
00401021 66 89 55 FC          mov         word ptr [ebp-4],dx
7:         char a;
8:         char buf2[10]="222222222";//在a后面留出10字节
00401025 A1 AC 20 40 00       mov         eax,[string "222222222" (004020ac)]
0040102A 89 45 E4             mov         dword ptr [ebp-1Ch],eax
0040102D 8B 0D B0 20 40 00    mov         ecx,dword ptr [string "222222222"+4 (004020b0)]
00401033 89 4D E8             mov         dword ptr [ebp-18h],ecx
00401036 66 8B 15 B4 20 40 00 mov         dx,word ptr [string "222222222"+8 (004020b4)]
0040103D 66 89 55 EC          mov         word ptr [ebp-14h],dx
9:         char *str=&a;
00401041 8D 45 F0             lea         eax,[ebp-10h]
00401044 89 45 E0             mov         dword ptr [ebp-20h],eax
10:        strcpy(str,"hello");//hello和后面的'\0'隐含覆盖了a开始的6个字节
00401047 68 A4 20 40 00       push        offset string "hello" (004020a4)
0040104C 8B 4D E0             mov         ecx,dword ptr [ebp-20h]
0040104F 51                   push        ecx
00401050 E8 1F 00 00 00       call        strcpy (00401074)
00401055 83 C4 08             add         esp,8
11:        printf(str);
00401058 8B 55 E0             mov         edx,dword ptr [ebp-20h]
0040105B 52                   push        edx
0040105C FF 15 00 20 40 00    call        dword ptr [__imp__printf (00402000)]
00401062 83 C4 04             add         esp,4
12:        return 0;
00401065 33 C0                xor         eax,eax
13:   }
00401067 5F                   pop         edi
00401068 5E                   pop         esi
00401069 5B                   pop         ebx
0040106A 8B E5                mov         esp,ebp
0040106C 5D                   pop         ebp
0040106D C3                   ret

执行到9:         char *str=&a;时
0012FF54  32 32 32 32 32 32 32 32 32 00 00  222222222..
0012FF5F  00 68 FF 12 00 31 31 31 31 31 31  .h...111111
0012FF6A  31 31 31 00 

执行到11:        printf(str);时
0012FF54  32 32 32 32 32 32 32 32 32 00 00  222222222..
0012FF5F  00 68 65 6C 6C 6F 00 31 31 31 31  .hello.1111
0012FF6A  31 31 31 00 40 00 C0 FF 12 00 7F  111.

#25


“内存”变成“内在”。。。。。楼主用的是五笔?

#26


学习学习。。。。。。。。。。。。。。。。

#1


内存读写 100条经典C语言笔试题 不明白的地方

#2


1,没有为str分配内存空间,将会发生异常。
2,将一个字符串复制进一个字符变量指针所指地址。
字符型变量在32位机中只占1个字节,而字符串即使空也有占1个字节了,必须越界

#3



    char a;  //系统分配了一个字节给a
    char *str=&a; // 把a的地址给 str, 也就是str可用字节只有一个
    strcpy(str,"hello"); // 这里你“hello” 赋值到一个字节内存的 显然会内存出错的
    printf(str);
    return 0;

#4


指针可用空间不够

#5


指向的内存空间不够用呗

#6


"hello"有6个字节,而str指向占1个字节的内存空间,然后把6个字节的内容拷给一个字节的空间,你说越界不越界。

#7


说的不错,受教啦

#8



//首先,LZ应该明白越界,你申请了一个字节的空间,这个一个字节就是你自己定义的界限,
//然后你写了6个字节,那你就是越过你自己定义的界限了.
//函数堆栈中,变量之后的堆栈通常保存着函数返回的信息,你写越界了,也就破坏了那些信息,
//造成函数可能无法返回,程序就崩溃了。这也叫函数栈溢出。
int main()
{
    char a;//申请了一个字节的空间
    char *str=&a;
    strcpy(str,"hello");//写了6个字节的空间
    printf(str);
    return 0;
}

#9


引用 5 楼 qzf362269994 的回复:
指向的内存空间不够用呗
不是,是str这个指针不能去修改指向的内存的内容。。。如果想修改可以定义为char str[]的形式就可以了。试图去修改char *str。会出现内存出错。程序崩溃

#10


好吧,学习了。

#11



malloc 和 free

#12


综上所述,楼主明白了吧

#13



int main()
{
    char a;   //一个字节的空间
    char *str=&a;   //指向一个字节的空间
    strcpy(str,"hello");   //在一个字节的空间中放6个字节“hello”5个字母,加一个结束符
    printf(str);   //输出一个字节的空间中的内容。
    return 0;
}

#14


注意,str指向的空间大小是不确定的

#15


该回复于2013-07-31 08:43:29被管理员删除

#16


 int main()
 {

     char buf1[10];//在a前面留出10字节
     char a;
     char buf2[10];//在a后面留出10字节
     char *str=&a;
     strcpy(str,"hello");//hello和后面的'\0'隐含覆盖了a开始的6个字节
     printf(str);
     return 0;
 }

#17


引用 6 楼 dnvycumt3 的回复:
"hello"有6个字节,而str指向占1个字节的内存空间,然后把6个字节的内容拷给一个字节的空间,你说越界不越界。

hello是六个字节?真的假的?我刚学C,不知道是不是有什么厉害的东西。。。

#18


引用 17 楼 jssd64 的回复:
Quote: 引用 6 楼 dnvycumt3 的回复:

"hello"有6个字节,而str指向占1个字节的内存空间,然后把6个字节的内容拷给一个字节的空间,你说越界不越界。

hello是六个字节?真的假的?我刚学C,不知道是不是有什么厉害的东西。。。

"hello"后面有个结束符'\0'你看不到而已,按照惯例  上一段代码:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char str[] = "hello";
printf("%d\n", sizeof(str));//结果是6  
system("pause");
}

#19


同意三楼的 100条经典C语言笔试题 不明白的地方

#20


引用 16 楼 zhao4zhong1 的回复:
 int main()
 {

     char buf1[10];//在a前面留出10字节
     char a;
     char buf2[10];//在a后面留出10字节
     char *str=&a;
     strcpy(str,"hello");//hello和后面的'\0'隐含覆盖了a开始的6个字节
     printf(str);
     return 0;
 }
100条经典C语言笔试题 不明白的地方不一定是 一前一后的 

#21


100条经典C语言笔试题 不明白的地方

#22


100条经典C语言笔试题 不明白的地方

#23


100条经典C语言笔试题 不明白的地方

#24


1:    #include <string.h>
2:    #include <stdio.h>
3:    int main()
4:    {
00401000 55                   push        ebp
00401001 8B EC                mov         ebp,esp
00401003 83 EC 60             sub         esp,60h
00401006 53                   push        ebx
00401007 56                   push        esi
00401008 57                   push        edi
5:
6:         char buf1[10]="111111111";//在a前面留出10字节
00401009 A1 B8 20 40 00       mov         eax,[string "111111111" (004020b8)]
0040100E 89 45 F4             mov         dword ptr [ebp-0Ch],eax
00401011 8B 0D BC 20 40 00    mov         ecx,dword ptr [string "111111111"+4 (004020bc)]
00401017 89 4D F8             mov         dword ptr [ebp-8],ecx
0040101A 66 8B 15 C0 20 40 00 mov         dx,word ptr [string "111111111"+8 (004020c0)]
00401021 66 89 55 FC          mov         word ptr [ebp-4],dx
7:         char a;
8:         char buf2[10]="222222222";//在a后面留出10字节
00401025 A1 AC 20 40 00       mov         eax,[string "222222222" (004020ac)]
0040102A 89 45 E4             mov         dword ptr [ebp-1Ch],eax
0040102D 8B 0D B0 20 40 00    mov         ecx,dword ptr [string "222222222"+4 (004020b0)]
00401033 89 4D E8             mov         dword ptr [ebp-18h],ecx
00401036 66 8B 15 B4 20 40 00 mov         dx,word ptr [string "222222222"+8 (004020b4)]
0040103D 66 89 55 EC          mov         word ptr [ebp-14h],dx
9:         char *str=&a;
00401041 8D 45 F0             lea         eax,[ebp-10h]
00401044 89 45 E0             mov         dword ptr [ebp-20h],eax
10:        strcpy(str,"hello");//hello和后面的'\0'隐含覆盖了a开始的6个字节
00401047 68 A4 20 40 00       push        offset string "hello" (004020a4)
0040104C 8B 4D E0             mov         ecx,dword ptr [ebp-20h]
0040104F 51                   push        ecx
00401050 E8 1F 00 00 00       call        strcpy (00401074)
00401055 83 C4 08             add         esp,8
11:        printf(str);
00401058 8B 55 E0             mov         edx,dword ptr [ebp-20h]
0040105B 52                   push        edx
0040105C FF 15 00 20 40 00    call        dword ptr [__imp__printf (00402000)]
00401062 83 C4 04             add         esp,4
12:        return 0;
00401065 33 C0                xor         eax,eax
13:   }
00401067 5F                   pop         edi
00401068 5E                   pop         esi
00401069 5B                   pop         ebx
0040106A 8B E5                mov         esp,ebp
0040106C 5D                   pop         ebp
0040106D C3                   ret

执行到9:         char *str=&a;时
0012FF54  32 32 32 32 32 32 32 32 32 00 00  222222222..
0012FF5F  00 68 FF 12 00 31 31 31 31 31 31  .h...111111
0012FF6A  31 31 31 00 

执行到11:        printf(str);时
0012FF54  32 32 32 32 32 32 32 32 32 00 00  222222222..
0012FF5F  00 68 65 6C 6C 6F 00 31 31 31 31  .hello.1111
0012FF6A  31 31 31 00 40 00 C0 FF 12 00 7F  111.

#25


“内存”变成“内在”。。。。。楼主用的是五笔?

#26


学习学习。。。。。。。。。。。。。。。。