QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: youxiazhu

苦恼,很简单,就是编译不过去!

[复制链接]
发表于 2005-7-7 13:42:23 | 显示全部楼层
我的直觉告诉我 vector<string> 应该是 exception safe 的。把一个 vector<string> 放在栈上,出现异常的时候会自动析构;而这个 vector<string> 析构的时候会自动析构它在堆上管理的所有 string 并且释放内存。
不安全的是 vector<char *> 吧。
回复

使用道具 举报

发表于 2005-7-7 17:40:45 | 显示全部楼层
不好意思,我记漏了一点东西,原文如下:
From Exceptional C++ Item 17
Unfortunately, among other things, this means that inserting into and erasing from a vector<string> or a vector<vector<int> >, for example, are not strongly exception-safe.
回复

使用道具 举报

发表于 2005-7-7 21:16:46 | 显示全部楼层
呵呵,我手边没有 Exceptional C++。能不能提示一下 Item 17 是在说什么?
看你引用的内容好像是说,当需要在向一个 vector 中进行插入操作的时候导致内存分配失败可能导致整个 insert 操作失败并且处于一种非异常安全的情况?
回复

使用道具 举报

发表于 2005-7-7 23:47:18 | 显示全部楼层
Item 8~17是同一个专题Writing Exception-Safe Code
Item 17是讨论"Is the C++ standard library exception-safe?"
下面是讨论的全部。
Exception Safety and the Standard Library
Are the standard library containers exception-safe and exception-neutral? The short answer is: Yes.[14]

     [14] Here, I'm focusing my attention on the containers and iterators portion of the standard library. Other parts of the library, such as iostreams and facets, are specified to provide at least the basic exception-safety guarantee.

All iterators returned from standard containers are exception-safe and can be copied without throwing an exception.

All standard containers must implement the basic guarantee for all operations: They are always destructible, and they are always in a consistent (if not predictable) state even in the presence of exceptions.

To make this possible, certain important functions are required to implement the nothrow guarantee (are required not to throw)including swap (the importance of which was illustrated by the example in the previous Item), allocator<T>::deallocate (the importance of which was illustrated by the discussion of operator delete() at the beginning of this miniseries) and certain operations of the template parameter types themselves (especially, the destructor, the importance of which was illustrated in Item 16 by the discussion headed "Destructors That Throw and Why They're Evil").

All standard containers must also implement the strong guarantee for all operations (with two exceptions). They always have commit-or-rollback semantics so that an operation such as an insert either succeeds completely or else does not change the program state at all. "No change" also means that failed operations do not affect the validity of any iterators that happened to be already pointing into the container.

There are only two exceptions to this point. First, for all containers, multi-element inserts ("iterator range" inserts) are never strongly exception-safe. Second, for vector<T> and deque<T> only, inserts and erases (whether single- or multi-element) are strongly exception-safe as long as T's copy constructor and assignment operator do not throw. Note the consequences of these particular limitations. Unfortunately, among other things, this means that inserting into and erasing from a vector<string> or a vector<vector<int> >, for example, are not strongly exception-safe.

Why these particular limitations? Because to roll back either kind of operation isn't possible without extra space/time overhead, and the standard did not want to require that overhead in the name of exception safety. All other container operations can be made strongly exception-safe without overhead. So if you ever insert a range of elements into a container, or if T's copy constructor or assignment operator can throw and you insert into or erase from a vector<T> or a deque<T>, the container will not necessarily have predictable contents afterward and iterators into it may have been invalidated.

What does this mean for you? Well, if you write a class that has a container member and you perform range insertions, or you write a class that has a member of type vector<T> or deque<T>, and T's copy constructor or assignment operator can throw, then you are responsible for doing the extra work to ensure that your own class's state is predictable if exceptions do occur. Fortunately, this "extra work" is pretty simple. Whenever you want to insert into or erase from the container, first take a copy of the container, then perform the change on the copy. Finally, use swap to switch over to using that new version after you know that the copy-and-change steps have succeeded.
回复

使用道具 举报

 楼主| 发表于 2005-7-8 09:56:06 | 显示全部楼层
好深奥呕
回复

使用道具 举报

发表于 2005-7-8 11:54:26 | 显示全部楼层
Unfortunately, among other things, this means that inserting into and erasing from a vector<string> or a vector<vector<int> >, for example, are not strongly exception-safe.


看起来是这个意思:因为 vector<T> 的 insert 是可能 throw 的,string 的复制也可能 throw,而这种 throw 直接破坏了 vector<T> 本身 insert 时候的 exception-safe 的前提。
对于一个符合“T's copy constructor and assignment operator do not throw”的类型而言,vector<T> 是完全 exception-safe 的。
回复

使用道具 举报

发表于 2005-7-8 18:05:38 | 显示全部楼层
[quote:4af7f9224f="wolf0403"]Unfortunately, among other things, this means that inserting into and erasing from a vector<string> or a vector<vector<int> >, for example, are not strongly exception-safe.


看起来是这个意思:因为 vector<T> 的 insert 是可能 throw 的,string 的复制也可能 throw,而这种 throw 直接破坏了 vector<T> 本身 insert 时候的 exception-safe 的前提。
对于一个符合“T's copy constructor and assignment operator do not throw”的类型而言,vector<T> 是完全 exception-safe 的。[/quote]

同意
回复

使用道具 举报

发表于 2005-7-25 17:43:11 | 显示全部楼层
youxiazhu, 我遇到同樣問題, 請問你是如何解決?

tt.cpp
=============================
#include <string>

int main()
{
   string name;
   printf("\naaaaa\n");
   return 1;
}
=============================

g++ tt.cpp -o tt

error:
===============================================
tt.cpp: In function `int main()':
tt.cpp:5: `string' undeclared (first use this function)
tt.cpp:5: (Each undeclared identifier is reported only once for each function
   it appears in.)
tt.cpp:5: syntax error before `;' token
===============================================

linux 版本:
=============================================
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-20)
=============================================
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-5 15:53 , Processed in 0.046965 second(s), 12 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表