原因是文件名中有空格
2.
error: stray ‘\357’ in program
error: stray ‘\274’ in program
error: stray ‘\233’ in program
出现此类错误的原因,在编辑器中使用的utf-8的格式保存源代码中出现了中文的标点符号
3.
结果在gcc编译器下居然发出了警告:warning:suggest parentheses around assignment used as truth value
后来在网络上找了一下,看人家是这么解释的,即在C语言中,非0代表TRUE,反之为FALSE。atype值是用于最后的判断用的,但是由于长期的编程实践告诉我们,人们经常在"="和“==”的使用上出现手误,所以gcc编译器为此要求我们明确地告诉编译器它是"="而不是"==",是故意,而非手误。
if ( ( atype=search(alphatp, 1) ) ) 即加一个括号括起来就可以了。
4
return-statement with a value, in function returning 'void'
如果函数定义返回值是void, return NULL;是不对的,可以用return;
5.cannot declare member function to have static linkage
6.error: no matching function for call to 'std::queue
pop()是不带参数的。
7.struct hello_Android_dev' declared inside parameter list [enabled by default]
解决:看看结构体是不是没有定义,没有包含头文件,结构体最后没有加;
############1. read、write和close对应到C++库是什么函数
read write close 在#include
fread fwrite fclose 在stdio.h
read write close ---->系统调用 fread fwrite fclose ---->对应的库函数
The C Programming Language上有介绍
##############2. 使用gdb调试软件,如何进入所调用函数的内部(在另一个源文件内)
用断点(breakpoint)
break命令(可以简写为b)可以用来在调试的程序中设置断点,该命令有如下四种形式:
(gdb) break line-number 使程序恰好在执行给定行之前停止。
(gdb) break function-name 使程序恰好在进入指定的函数之前停止。
(gdb) break line-or-function if condition 如果condition(条件)是真,程序到达指定行或函数时停止。
(gdb) break routine-name 在指定例程的入口处设置断点
如果该程序是由很多原文件构成的,你可以在各个原文件中设置断点,而不是在当前的原文件中设置断点,其方法如下:
(gdb) break filename:line-number
(gdb) break filename:function-name
要想设置一个条件断点,可以利用break if命令,如下所示:
(gdb) break line-or-function if expr
例:
(gdb) break 46 if testsize==100
从断点继续运行:countinue 命令
http://fanqiang.chinaunix.net/program/other/2006-07-14/4834.shtml
###############3. 怎么设定string的长度?
可以啊,string data(n,'c')初始化为字符'c'的n个副本
就能在初始化时设定固定的大小了
调用string.reverse可以预先申请空间
##############4. int length() const;中const的作用
类成员函数中const的使用
一般放在函数体后,形如:void fun() const;
任何不会修改数据成员的函数都该声明为const类型。如果在编写const成员函数时,不慎修改了数据成员,或者调用了其他非const成员函数,编译器将报错,这大大提高了程序的健壮性。
1. 不能对成员进行赋值。
2. 不能调用非const成员函数。
3. 将类数据成员传递给外部函数时,将为该数据成员加上const属性。
#################5. 关于双向链表尾部添加
书上说在中间和尾部节点后添加的代码是一致的:
q->next=p->next;
q->prior=p;
p->next->prior=q;
p->next=q;
尾部添加时 p->next->prior=q;有意义吗?不是 p->next就是NULL了吗?谁解释下
那就是书上错了
在p->next->prior=q; 前判断一下p->next!=NULL就可以通用
################6. .c转为.cpp出错
server.cpp:67: 错误:从类型 ‘int*’ 到类型 ‘socklen_t*’ 的转换无效
server.cpp:67: 错误: 初始化实参 3,属于 ‘int accept(int, sockaddr*, socklen_t*)
server.cpp:73: 错误:‘inet_ntoa’ 在此作用域中尚未声明
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),
&sin_size))==-1)
should be
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),
(socklen_t*)&sin_size))==-1)
replace inet_ntoa with inet_ntop, the latter is recommended and add header files
#include
#include
#include
###############7。 运行autoscan时出错如下,是什么原因?
autom4te: configure.ac: no such file or directory
autoscan: /usr/bin/autom4te failed with exit status: 1
不影响正常使用
##############8 fork执行的问题
总是把pid == 0执行很多次,在执行父进程很多次,不是应该交叉执行的吗 ?
void main()
{
int rtn; /*子进程的返回数值*/
while(1)
{
/* 从终端读取要执行的命令 */
int pid = fork();
if ( pid == 0 )
{
/* 子进程执行此命令 */
execlp("ls", "ls", "-al", "/etc/passwd", 0);
/* 如果exec函数返回,表明没有正常执行命令,打印错误信息*/
perror("ERROR!!!!!!!!!!!!!!!!");
exit(errno);
}
else
{
/* 父进程, 等待子进程结束,并打印子进程的返回值 */
wait ( &rtn );
printf( " child process return %dn",rtn );
}
}
}
fork之后,父进程和子进程执行的顺序,没有固定的规定,一切皆有可能
##############9 这段程序怎么不执行printf("child");呢?
C/C++ code
int fork2(void) { pid_t pid; pid = fork();
if(pid < 0) { perror("fork error"); }
else if(pid == 0) //在这一块,用一个if语句来判断这一部分是子进程的代码空间
{ printf("child"); if(execlp("ls", "ls", "-al", "/etc/passwd", 0) < 0) perror("execl (ls) error"); }
else { //对应的父进程的代码空间 wait((int *)0); // wait 语句可以用来等待子进程结束。 printf("done!\n"); }
exit(0);
改成printf("child\n");就好了,可能是刷新缓存的事
printf("child");
追加
flush();
################10为什么traceroute测出的延时比ping测出的大,都是一跳的
如果是一跳的平均时间的话,可能是因为traceroute每一跳都得给主机返回一个超时ICMP报文
##############11 const char *ct 是限制ct不变还是*ct不变,还是两者都受限制不变?
限制*ct不变
const char *ct //限制*ct不变
char * const ct //限制ct不变
const char *const ct//两者都限制
#################12 又见段错误,不知原因
/bin/sh:line 1:7315 段错误
host.c
C/C++ code
int main(int argc, char *argv[])
{
printf("Hello, world!\n");
char *s1="wo shi ge hao hai zi!";
char *s2 = (char *)malloc(50);
char *s3="cai bu shi"; char *s4=strchr(s1,'j');
if(*s4!=NULL)
{ printf("%s\n",s4); }
free(s2);
return EXIT_SUCCESS;
}
if(*s4!=NULL)
这句明显的错误么。 应该是if(s4 != NULL )
错误的那句是因为s4为NULL(即0) ,*s4 当然会段错误,因为访问的是 0地址
可以编译过是因为他把那个表达式作为算数表达式了
检查关系表达式两端的数据类型是否匹配
如果你编译的时候不要关闭警告,因该会有 warning: NULL used in arithmetic 这么一句警告的
该错误是在LINUX下用Kdevelop出现的,是怎么回事哩?
/bin/sh: line : 13397 段错误
工程中有3个源文件 :
host.c
C/C++ code
#include
#include
#include "str.h"
int main(int argc, char *argv[])
{ printf("Hello, world!\n"); char *s1="wo shi ge hao hai zi!";
char *s2; strcpy(s2,s1);
return EXIT_SUCCESS; }
没有分配内存。
char *s2 = new char[100];
##################13 文件发送问题
我上面写的有问题,接收端不负责文件大小
问题是
long filesize(FILE *stream)
{
long curpos, length;
curpos = ftell(stream);
fseek(stream, 0L, SEEK_END);
length = ftell(stream);
fseek(stream, curpos, SEEK_SET);
return length;
}
把回车换行当成两个字符,发送只把它当成一个字符'\10',结果就多发送出去回车换行个垃圾字符
看来filesize该修正了,怎么才能把回车换行当成一个字符。。
问题解决啦
我不用filesize算出的长度,用fread返回的长度就行了
谢谢大家帮忙,特别是dahua010
##################14 字符串拷贝的问题
char *strcpy(char *dest, const char *src)
void *memcpy(void *dest, const void *src, size_t n)
而strcpy(str,pack->GetPayloadData());中的
pack->GetPayloadData()返回的是unsigned char *
所以报错cannot convert parameter 2 from 'unsigned char *' to 'const char *'
是不是memcpy功能比strcpy强,可以替代它?
memcpy内存拷贝,不过也是经常用于字符串。
strcpy以'\0'结束字符数组拷贝。
LZ的问题应该可以转换下 void * 和 char *
原来早期版本 参数是 char * ,后来使用类属指针来代替 char *,消除一些强制转换
#################15 例子中接收代码收到的数据包,是放在RTPPacket结构中,而且接收代码只返回了RTPPacket大结构,没有关于payload的返回,想要保存接收的数据包怎么办?
GetPayloadData,你要的是这个方法吗 ?
#################16打开文件为什么是空?
fp=fopen("C:\Lw.txt","r+");
C:\\Lw.txt 双斜杠
##################16 对继承函数的调用问题
在类RTPSession中有一个虚函数:
virtual void OnPollThreadStep() { }
我在MyRTPSession 中把它实现:
class MyRTPSession : public RTPSession
{
protected:
void OnPollThreadStep();
调用的部分是这样的:
RTPSession &rtpsession;
rtpsession.OnPollThreadStep();
但是函数调用还是调用RTPSession中的那个,而不是MyRTPSession 中的那个,为什么啊?
MyRTPSession instance;
RTPSession *p = &instance;
p->OnPollThreadStep();
上面的方式应该调用子类的函数了。
################17 在c程序中调用C++lib库jrtplib的问题
jrtplib 好象是用c++写的,提供了类接口
如果你想用c调用,你可能要再用c++封装一层,然后再给c调用
简单的说,就是,把对象的方式转换成过程的方式;
比如:
RTPSession sess;
sess.Create()
sess.AddDestination();
写成用C能认得的方式:
RTPSession sess;
int Create()
{
sess.Create();
return 0;
}
int AddDestination()
{
sess.AddDestination();
return 0;
}
在C中调用C++的函数可以加一个声明
extern "C++" void func();
试着在C中用extern "C++"声明导入C++编写的jrtplib库函数
######################18 这个程序有个小问题,buf接收正确,但是打印不出来,谁知道说说啊
找到了,问题出在这句上,
if((numbytes=recv(sockfd,buf,MAXDATASIZE-1,0)==-1))
改为
if((numbytes=recv(sockfd,buf,MAXDATASIZE-1,0))==-1)
就好了.
###############19 Redhat AS4 中没有ifconfig
不在root下不能使用一些命令,如:ifconfig,ifup,ifdown等.我一直是用普通用户登录的,所以不能用.
#################20 什么时候调用构造函数?
(1) 在全局范围中定义的对象(即在所有函数之外定义的对象),它的构造函数在文件中的所有函数(包括main函数)执行之前调用。但如果一个程序中有多个文件,而不同的文件中都定义了全局对象,则这些对象的构造函数的执行顺序是不确定的。当main函数执行完毕或调用exit函数时(此时程序终止),调用析构函数。
(2) 如果定义的是局部自动对象(例如在函数中定义对象),则在建立对象时调用其构造函数。如果函数被多次调用,则在每次建立对象时都要调用构造函数。在函数调用结束、对象释放时先调用析构函数。
(3) 如果在函数中定义静态(static)局部对象,则只在程序第一次调用此函数建立对象时调用构造函数一次,在调用结束时对象并不释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用析构函数。
##################21 构造函数与析构函数的执行顺序
构造函数顺序为:
1. 全局对象的构造函数;
2. main函数中对象的构造函数,包括automatic、static依次调用;
3. main中遇到函数中有局部对象时,进入到函数中调用局部对象的构造函数。
注:static对象的构造函数永远只调用一次。
析构函数顺序为:
1. 退出函数时,执行函数内构造的automatic对象的析构函数,注:static对象不析构;
2. main函数中按构造的逆序析构automatic对象;
3. 调用函数中定义的static对象的析构函数;
4. 调用main中定义的static对象的析构函数;
5. 最后调用全局对象的析构函数。
注:复合中的构造、析构顺序
构造:按声明对象的顺序来构造成员对象,而不是按照构造函数成员初始值列表中列出的顺序;而且在包含它们的类对象(宿主对象)被构造之前构造。即:由内向外构造。
析构:按对象构造的逆序析构。对于复合对象,先析构主对象,再析构其包含的对象。
#################22 .so文件是什么文件
.so是unix的动态连接库,是二进制文件,作用相当于windows下的.dll文件
###################23 如何输入空格
使用gets,不使用scanf,scanf把空格当作结束符,无法输入。
###################24 参数对等关系
const char *与数组名,与字符串
###################25 类对象大小与类大小的区别
类是数据类型;类对象是类的一个实例。
一个类对象所占据的内存空间由他的数据成员所占据的空间总和所决定,类的成员函数不占据类对象的内存空间;类的空间大小则要包括所有的空间大小了,而且只有在实例化后才分配内存空间。
class A
{
virtual void foo();//导致类里面有一个指向虚拟函数的指针vptr(虚拟函数表指针),4个字节
int i;
char c;
};
// sizeof(A) = 12
class B :public A
{
void foo1();
static int haha;
long ll;
} ;
//sizeof(B) = 16
class C : virtual public A//导致类里面有一个指向虚拟基类的指针p,4个字节
{
char sz[10];
};
// sizeof(C) = 28
如果是32位计算机,则
A的大小是:4(int)+4(char与int字节对齐)+4(vptr);
B的大小是:4(long)+12(A的大小)=16;
C的大小是:A的大小12+C的大小(12+4)=28;
如果C虚拟继承多个类,就有多个指针p
###################26 关于成员函数
C++里类的成员函数和C里的孤立函数在实现机制上基本想同,只是成员函数通过this指针操作对象的成员变量而已,例如a.fun()是通过fun(a.this)来调用的,this指针指向一个table,table里面记录的各个成员函数的地址(当然不同的编译可能略有不同的实现)。所以我们访问成员函数是间接获得地址的。所以这样也就增加了一定的时间开销,这也就是为什么我们提倡把一些简短的,调用频率高的函数声明为inline形式。。
###################27 C++标准问题
因为这些实质上的不同,你不能在一个程序中混淆使用这两个库。做为一种习惯,在新的代码中一般使用
在 C++ 标准化的过程中, C++ Standard Library headers的文件名, 全部都不含 file extension. 同时, 所有的名字都放在 'std' 这个 namespace 里面.
如果可能的话, 不要用 VC++6.0。 6.0版出来的时候, C++还没标准化. 6.0 的 C++ Standard Library 是老标准的版本,存在很多的 bug.
VC++ 7.1版以后已经遵循了标准化!
///
#####################28 gdb调试中查看局部变量为什么显示No symbol "q" in current context.
不再同一个文件中,变量作用域已经结束,当然找不到
#####################29 double free or corruption (fasttop): 0x0829b008 ***
内存释放两次引起的
########################30 字符串常量存在静态数据区,可以称之为一个无名的静态变量。
#include
//返回的是局部变量的地址,该地址位于动态数据区,栈里
char *s1()
{
char p[]="Hello world!";
printf("in s1 p=%p\n", p);
printf("in s1: string's address: %p\n", &("Hello world!"));
return p;
}
//返回的是字符串常量的地址,该地址位于静态数据区
char *s2()
{
char *q="Hello world!";
printf("in s2 q=%p\n", q);
printf("in s2: string's address: %p\n", &("Hello world!"));
return q;
}
//返回的是静态局部变量的地址,该地址位于静态数据区
char *s3()
{
static char r[]="Hello world!";
printf("in s3 r=%p\n", r);
printf("in s3: string's address: %p\n", &("Hello world!"));
return r;
}
函数返回时,先将返回值存入寄存器,然后释放局部变量空间,最后ret.
返回局部变量没问题
如果返回局部变量有问题,函数的意义还有吗? 全局变量还用返回吗?
返回指向局部变量的指针才有问题,
函数退栈之后,局部变量消失, 指针将指向未知区域,所以出现问题。
返回局部变量的引用也是绝对不可以的。
引用只是变量的一个别名,变量本体都不存在了,引用当然也没有任何意义。
还有,如果是堆空间,可以返回
即在函数中用new申请的空间,是可以返回的, 但是一般的情况下,好的风格是: 尽量在同一个作用域内成对使用new 和delete,(也即不要返回堆空间) 因为如果不是这样,会是你的函数的接口变的不够灵活, 试想每个调用你的函数的人还需要记得去delete掉你在函数中new的堆空间, 否则就会造成内存泄露。
std::vector
{
vecInt m_vecint;
m_vecint.push_back(2); //这种基本类型构造,vector的allocator会自动分配空间存储
//没问题局部变量被销毁,内部依然存在一份copy sample
return m_vecint;
}
然而对于array却是不同的
std::vector
{
int a[10] = {0};
vector
m_vecint.push_back(a); //此时返回后就会出现你说的问题局部变量被释放
//push指针管理区域无效
return m_vecint;
}
class a;
a fun()
{
a o;
return o;
}
这返回的是个临时对象,是对象o的拷贝,如果有拷贝构造函数(你可以建一个拷贝构造函数),你可以看得出来。
o是局部变量,但返回的不是o本身,所以没有问题。
但是如果写成:
a& fun()
{
a o;
return o;
}就不行了。
#########################31 Debug正确,release不正确, 一般都是优化的问题吧
#########################32 effective C++认为基类析构函数一定要虚函数,否则不会析构
#########################33 setvbuf和setbuf有没有作用?
Controls stream buffering and buffer size.
setbuf和setvbuf修改的缓冲是标准IO库的缓冲,缓冲一共3种:全缓冲、行缓冲、不缓冲. 默认情况终端输出为行缓冲,标准错误输出为不缓冲,文件IO操作为全缓冲.
如果你内存大,就可以把buf弄大点,减少磁盘IO的次数,从而获得更好的效率.
如果在一个读写频繁的程序里,经常seekg/seekp.那你认为缓冲区大小对性能没有一点帮助?如果单纯的读写磁盘,顺序的,台式机硬盘一般一次读写8K(具体数字忘了)是最快的.那缓冲区太大,也的确没多大效果.
std::fstream处理起来确实慢。
setvbuf很有用,在大量的读写中可以有效的提高效率。
std::fstream在默认情况下,比FILE*慢,在debug情况下更慢。因为std::fstream对buf操作比较多,函数调用比较多,这个问题在release模式下可以解决。其次std::fstream如果对buf调整得当,跟fwrite不相上下,甚至更快。
std::fstream怎么调整buf?那个setbuf似乎设置了无用。所以我现在基本上坚持 用FILE *,fopen,或者用CFile
ofs.rdbuf()->pubsetbuf()
这个要看具体情况。比如我这里,release模式 一次写16 K数据
不设置的情况是
std::ofstream = 0.273 ms
fwrite = 0.077 ms
设置8K buf
std::ofstream = 0.184 ms
fwrite = 0.069 ms
设置16 K buf
std::ofstream = 0.060 ms
fwrite = 0.069 ms
############################34 如何去除文件中的标点
FILE * fp;
char* fpBuffer = NULL;
fp = fopen("list.txt","r");
fscanf(fp,"%s",fpBuffer);
1
char szId[32] = { 0 };
char szName[32] = { 0 };
char szPhone[32] = { 0 };
sscanf(fpBuffer, "%s,%s,%s", szId, szName, szPhone);
2
char seps[] = ",";
char szId[32] = { 0 };
char szName[32] = { 0 };
char szPhone[32] = { 0 };
char *token = NULL;
token=strtok(fpBuffer,seps);
while(token!=NULL)
{
++i;
switch(i)
{
case 1:
strcpy(szId,token);
break;
case 2:
strcpy(szName,token);
break;
case 3:
strcpy(szPhone,token);
break;
default:
break;
}
token = strtok(NULL,seps);
}
############################35 linux多进程退出问题
kill 进程号 发送的是 SIGTERM
kill -9 进程号 发送的是 SIGKILL
主进程被kill掉后,子进程的父进程就是成pid为1的init进程
kill 进程号 发送的是 SIGTERM --SIGTERM这个是默认信号值
杀死进程就是 kill -9 进程号 --等同与KILL -KILL 进程号 所有的信号都是整型值,也可以用类似SIGKILL这样的宏来代替,如果记不住整型值,就用SIG后面的单词就行了。 如 kill -9 PID== kill -KILL PID
怎么释放子进程?
--这个你不用担心 ,主进程退出了 子进程由init托管,会自动释放的。倒是子进程先于主进程退出了比较麻烦。(可以google一下僵尸进程的问题)
如果你一定要作什么特殊的清理工作,
就在主进程收到信号后调用自己的信号捕捉器(sigin或者sigaction函数的指针) 子自己的捕捉器里写你要实现的东西。
如果你非要在主进程退出前干掉所有的子进程, 那就在主进程收到信号后在向所有子进程发信号吧。很多信号的默认捕捉器都是终止进程,可以查查,呵呵。
#############################36 (int*)*((int*)*((int*)&f))
class father{};
father f;
debug下,函数名的值以及函数指针变量的值不是函数的代码的起始地址,函数名的值对应的地址里是一条jmp指令,是无条件跳转到函数的代码的起始地址出。所以&father::test和(int*)*((int*)*((int*)&f))值不必一样,只要其对应的地址里的jmp指令都能跳转到test起始代码处就行。
realse下,函数的值以及函数指针变量的值则是是函数的代码的起始地址,所以&father::test和(int*)*((int*)* ((int*)&f))值可能一样,(int*)*((int*)*((int*)&f))的值是test函数的代码的起始位置,关键是编译器如何解析的&father::test了。
以上分析基于vc2005~~~,lz还是自己反汇编分析下吧。
//(int*)*( (int*)*( (int*)&f) )
int *pfather = (int*)&f; //将father对象作为整型指针数组
int *pvtable = (int*)*(pfather); //取其第一元素,即虚表地址,存储了虚函数指针
int *pvfun = (int*)*pvtable; //取虚表第一元素,即虚表第一个虚函数指针
void (*vf)() = (void(*)())*pvtable; //转换为函数指针
vf(); //调用该函数
#################################37 在程序中一用fork,收到的数据中的中文和标点部分就全是乱码,为什么呢?
加在while(1)中了,恐怖,随后死机。
############################38 linux中选用的定时方法
一usleep
二select
timeval tv;
tv.tv_sec = nSec;
tv.tv_usec = uSec;
int nRetVal = select( NULL , 0 , 0 , NULL , &tv );
三修改系统时间中断
四ualarm
五#include
int gettimeofday(struct timeval *tv, struct timezone *tz);
六alarm()
然后用single捕捉信号,调用你的发送函数
七void set_timer()
{
struct itimerval itv, oldtv;
itv.it_interval.tv_sec = 5;
itv.it_interval.tv_usec = 0;
itv.it_value.tv_sec = 5;
itv.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, &oldtv);
}
void sigalrm_handler(int sig)
{
count++;
printf("timer signal.. %d\n", count);
}
int main()
{
signal(SIGALRM, sigalrm_handler);
set_timer();
while (count < 1000)
{}
exit(0);
}
############################39
scalar object ‘pdata’ requires one element in initializer