@zsh-o
2018-07-16T23:53:14.000000Z
字数 2014
阅读 1184
C++
今天写程序出现了错误,如下
/*
* 对一个句子进行反转,每个词不反转
*/
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
/*
* 对一个字符串逆序
*/
char* reverse_string(char* s, int size_s){
char* r = new char[size_s];
int i = 0;
while(i < size_s){
int j = size_s - 1 - i;
r[i] = s[j];
i++;
}
return r;
}
char* reverse_string_(char* s, int size_s){
int i = 0;
while(i < size_s/2){
char a = s[i];
int j = size_s - 1 - i;
s[i] = s[j];
s[j] = a;
i++;
}
return s;
}
int main(){
char* s = "abcdefg";
printf("%s\n", reverse_string(s, strlen(s)));
// printf("%s\n", reverse_string_(s, strlen(s))); // s定义在栈区无法赋值
char* ss = new char[100];
for(int i=0; i<=strlen(s); i++){ //把'\0'复制过去
ss[i] = s[i];
}
printf("%s\n", reverse_string_(ss, strlen(ss)));
}
printf("%s\n", reverse_string_(s, strlen(s)));
出现了运行时错误,s
是字符串常量,被分配在了静态的常量区,再如下
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int main(){
char* s1 = "abcdefg";
char* s2 = "abcdefg";
char a1[] = "abcdefg";
char a2[] = "abcdefg";
const char ca1[] = "abcdefg";
const char ca2[] = "abcdefg";
const char* cs1 = "abcdefg";
const char* cs2 = "abcdefg";
printf("%d %d %d %d %d", s1==s2, a1==a2, ca1==ca2, cs1==cs2, s1==cs1);
}
1 0 0 1 1
可以看出char *
和const char *
均是字符串常量,其相同字符串指向同一个内存地址,无法赋值,而char []
和const char []
是局部字符数组变量,拥有各自的内存地址空间,被分配在栈区(局部变量分配在栈区,变量声明周期结束(函数结束)会被自动释放),下面程序正常执行
char* s = "abcdefg";
printf("%s\n", reverse_string(s, strlen(s)));
// printf("%s\n", reverse_string_(s, strlen(s))); // s定义在栈区无法赋值
char a[] = "abcdefg";
printf("%s\n", reverse_string(s, strlen(s)));
printf("%s\n", reverse_string_(a, strlen(a)));
最后来看看局部变量的释放:
#include <stdio.h>
#include <string.h>
char* fun(){
char s[] = "abcdefg";
printf("Fun: %p: %s --- %p \n", s, s, &s);
return s;
}
char* nfun(){
char *s = new char[100];
s = "abcdefg";
printf("NFun: %p: %s --- %p \n", s, s, &s);
return s;
}
int main(){
char* s = fun();
printf("Main: %p: %s --- %p\n", s, s, &s);
char* ns = nfun();
printf("NMain: %p: %s --- %p \n", ns, ns, &ns);
}
Fun: 0062FED8: abcdefg --- 0062FED8
Main: 00000000: (null) --- 0062FF0C
NFun: 0041A039: abcdefg --- 0062FEDC
NMain: 0041A039: abcdefg --- 0062FF08
其中%p s
代表指针s
指向的地址,%s s
代表输出字符串,%p &s
代表指针s
本身的内存地址
这里可以看到在fun()
函数里面s
是一个局部字符数组变量,被分配在了该函数的栈区,当函数结束时该指针被释放,则该函数返回的地址为空,则main
函数里面的s指向的地址为空(00000000)
。而nfun()
函数里面的s
用new
分配在了堆区,被用户申请和释放,故函数结束时仍然存在