| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 790 人关注过本帖
标题:自学Thinking in C++,第四章程序疑问,求解
只看楼主 加入收藏
jsczbnhc
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2011-10-8
结帖率:0
收藏
已结贴  问题点数:20 回复次数:3 
自学Thinking in C++,第四章程序疑问,求解
首先是头文件:
//: C04:CLib.h
// Header file for a C-like library
// An array-like entity created at runtime
typedef struct CStashTag {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
// Dynamically allocated array of bytes:
unsigned char* storage;
} CStash;
void initialize(CStash* s, int size);
void cleanup(CStash* s);
int add(CStash* s, const void* element);
void* fetch(CStash* s, int index);
int count(CStash* s);
void inflate(CStash* s, int increase);
///:~
然后中间是一个cpp文件
//: C04:CLib.cpp {O}
// Implementation of example C-like library
// Declare structure and functions:
#include "CLib.h"
#include <iostream>
#include <cassert>
using namespace std;
// Quantity of elements to add
// when increasing storage:
const int increment = 100;
void initialize(CStash* s, int sz) {
s->size = sz;
s->quantity = 0;
s->storage = 0;
s->next = 0;
}
int add(CStash* s, const void* element) {
if(s->next >= s->quantity) //Enough space left?
inflate(s, increment);疑问1:这里是扩大储存空间的,那么上面一句不是应该把">="改为"<"
// Copy element into storage,
// starting at next empty space:
int startBytes = s->next * s->size;
unsigned char* e = (unsigned char*)element;
for(int i = 0; i < s->size; i++)
s->storage[startBytes + i] = e[i];
s->next++;
return(s->next - 1); // Index number
}
void* fetch(CStash* s, int index) {
// Check index boundaries:
assert(0 <= index);
if(index >= s->next)
return 0; // To indicate the end
// Produce pointer to desired element:
return &(s->storage[index * s->size]);
}
int count(CStash* s) {
return s->next; // Elements in CStash
}
void inflate(CStash* s, int increase) {
assert(increase > 0);
int newQuantity = s->quantity + increase;
int newBytes = newQuantity * s->size;
int oldBytes = s->quantity * s->size;
unsigned char* b = new unsigned char[newBytes];
for(int i = 0; i < oldBytes; i++)
b[i] = s->storage[i]; // Copy old to new
delete [](s->storage); // Old storage
s->storage = b; // Point to new memory
s->quantity = newQuantity;
}
void cleanup(CStash* s) {
if(s->storage != 0) {
cout << "freeing storage" << endl;
delete []s->storage;
}
} ///:~
最后是主函数
//: C04:CLibTest.cpp
//{L} CLib
// Test the C-like library
#include "CLib.h"
#include <fstream>
#include <iostream>
#include <string>
#include <cassert>
using namespace std;
int main() {
// Define variables at the beginning
// of the block, as in C:
CStash intStash, stringStash;
int i;
char* cp;
ifstream in;
string line;
const int bufsize = 80;
// Now remember to initialize the variables:
initialize(&intStash, sizeof(int));
for(i = 0; i < 100; i++)
add(&intStash, &i);//add函数传递是一个struct类型指针和一个数组指针,这里传递了整型变量"i"到add函数,然后在add函数中强制转\\换为unsigned char类型,而且是一个数组,这个做何解,难道是给storage数组传递从第一个数依次到第八数(int型位数为八位)?求解?
for(i = 0; i < count(&intStash); i++)
cout << "fetch(&intStash, " << i << ") = "
<< *(int*)fetch(&intStash, i)
<< endl;
// Holds 80-character strings:
initialize(&stringStash, sizeof(char)*bufsize);
in.open("CLibTest.cpp");
assert(in);
while(getline(in, line))
add(&stringStash, line.c_str());
i = 0;
while((cp = (char*)fetch(&stringStash,i++))!=0)
cout << "fetch(&stringStash, " << i << ") = "
<< cp << endl;
cleanup(&intStash);
cleanup(&stringStash);
} ///:~
搜索更多相关主题的帖子: 自学 allocated quantity library created 
2011-11-03 01:51
jsczbnhc
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2011-10-8
收藏
得分:0 
另外,这个函数编译通过后为什么会产生segmentation fault这样的错误呢?
2011-11-03 02:41
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
收藏
得分:20 
楼主可能对CStash的功能还没弄明白,我可以跟你解释一下:
程序代码:
typedef struct CStashTag {
    int size; // Size of each space 每个元素所占的内存空间大小(字节数量)
    int quantity; // Number of storage spaces 实际已经分配的内存空间大小(字节数量)
    int next; // Next empty space 下一块空的字节内存块的地址(索引)
    // Dynamically allocated array of bytes:
    unsigned char* storage; 动态内存块的地址
} CStash;

initialize: 初始化CStash中的字段,主要是通过参数sz设置size字段,这样我们就知道每个元素所占内存大小,其它字段都初始化为0。
add: element指向的内存块复制到storage指向的内存块中(通过next * size计算得到地址后,从element复制size个字节到storage,size是通过initialize初始化的,还记得吗?),如果是第一次调用add函数,那么storage还没有指向一块有效的内存块(因为还没有用new分配空间),并且next == 0,quantity == 0,if(s->next >= s->quantity)就成立,所以就会调用inflate来增加内存空间(这里其实是第一次分配内存空间),第二种情况:next != 0 && next == quantity(或next >= quantity),那么空间已经不够(作者用next >= quantity其实是出于一种担心,怕next被恶意修改,不意外可以用next == quantity来判断),next == quantity代表next已经指向最后一个元素的后面,这里是一个不存在的空间,所以也要调用inflate来增加storage指向内存的大小。复制成功后next指向下一个未使用的内存块,并返回存入数据的位置(索引)。
fetch: 返回指向index对应的内存块的地址。通常需要通过上下文对返回值进行分析。
inflate: 增大storage的内存空间,新的大小是quantity + increase的大小,把原来的数据复制到新分配的内存中,然后释放原来的内存空间。
count: 返回元素的个数(其实就是next的值)。
cleanup:释放storage指向的内存空间。

这个程序有点模仿STL里的vector,其实就是把数据放到一块new分配的内存块中,不够时增大容量以保证可以继续存入数据。


[ 本帖最后由 lz1091914999 于 2011-11-3 13:07 编辑 ]

My life is brilliant
2011-11-03 12:59
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
收藏
得分:0 
3章和4章偏向于C,如果有C的基础也可以跳过去,而且不建议看翻译的,要看还是看英文版,中文版有的地方很晦涩难懂。

My life is brilliant
2011-11-03 13:12
快速回复:自学Thinking in C++,第四章程序疑问,求解
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025264 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved