Symbian基础总结 -- 验证RArray::Append是否保存对象副本

 原文出处: http://www.cnblogs.com/felixYeou/archive/2008/11/20/1337780.html

 

一、验证栈对象会自动销毁

我们知道,在C++中,在函数中创建了栈对象,函数退出时,该栈对象会自动销毁(栈指针后移了,栈内存会被覆盖)。如何验证这一点?我们需要在函数外定义一个整形变量,在函数内将该函数内获取了变量的地址,在函数调用完毕后,将地址还原成对象:

TInt iAddr;

/** 
* 将地址还原成描述符对象并显示出来 
* @param aAddr 地址 
*/ 
LOCAL_C void PrintString(TInt aAddr) 
    { 
    const TBufC<50>& str = *((TBuf<50>*)aAddr); 
    console->Write(str); 
    }

LOCAL_C void DoTest() 
    { 
    _LIT(KString, "Test String"); 
    TBufC<50> str(KString); 
    // 获取栈对象str的地址: 
    iAddr = (TInt)&str; 
    PrintString(iAddr);    // 此处可以正常显示出“Test String” 
    }

LOCAL_C void MainL() 
    { 
    DoTest();    
    PrintString(iAddr);    // 此处显示乱码,证明栈对象会自动销毁 
    }

 

二、试验:RArray::Append方法会保存对象的副本

typedef TBufC<20> TFixedBufC; 
RArray<TFixedBufC> iArr;

LOCAL_C void DoInsert() 
    { 
    TFixedBufC text1(_L("test1")); 
    iArr.Append(text1); 
    }

LOCAL_C void MainL() 
    { 
    DoInsert(); 
    TFixedBufC& desc = iArr[0]; 
    console->Write(desc); 
    }

输出结果:

image

按照第一点分析,DoInsert函数内的栈对象text1会在DoInsert函数返回的时候被自动销毁,如果RArray::Append方法只是简单的保存了text1的引用的话,程序不可能能够正确的输出test1。所以,我们通过此试验证明Append方法中构建了一个text1的副本。

 

三、证明:RArray::Append方法会保存对象的副本

typedef TBufC<20> TFixedBufC; 
RArray<TFixedBufC> iArr;

LOCAL_C void DoInsert() 
    { 
    TFixedBufC text1(_L("test1")); 
    TBuf<50> addrStr;


    // 获取text1的地址 
    addrStr.AppendNum((TInt)&text1); 
    iArr.Append(addrStr); 
    console->Write(addrStr); 
    console->Write(_L("/n")); 
    }

LOCAL_C void MainL() 
    { 
    DoInsert(); 
    TFixedBufC& desc = iArr[0]; 
    TBuf<50> addrStr;


    // 获取desc的地址 
    addrStr.AppendNum((TInt)&desc); 
    console->Write(addrStr); 
    }

image

我在函数DoInsert内获取了描述符text1的地址并显示,并将描述符text1使用RArray::Append方法添加到了集合内,在MainL方法内获取了集合第一个元素的引用并将该引用的地址输出。大家可以看到,输出的两个地址并不相同,从而证明了RArray::Append方法创建了对象的副本并保存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是实现该功能的C语言代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #pragma pack(1) // 确保结构体按照1字节对齐 // BMP文件头结构体 typedef struct { char bfType[2]; // 文件类型,必须为"BM" int bfSize; // 文件大小,单位为字节 short bfReserved1; // 保留字段,必须为0 short bfReserved2; // 保留字段,必须为0 int bfOffBits; // 数据偏移量,即位图数据从文件头开始的偏移量 } BMPFILEHEADER; // BMP信息头结构体 typedef struct { int biSize; // 信息头大小,必须为40 int biWidth; // 图像宽度,单位为像素 int biHeight; // 图像高度,单位为像素 short biPlanes; // 位平面数,必须为1 short biBitCount; // 每个像素的位数,必须为32 int biCompression; // 压缩类型,必须为0 int biSizeImage; // 图像数据大小,单位为字节 int biXPelsPerMeter; // 水平分辨率,单位为像素/米 int biYPelsPerMeter; // 垂直分辨率,单位为像素/米 int biClrUsed; // 颜色表中实际使用的颜色数,必须为0 int biClrImportant; // 重要的颜色数,必须为0 } BMPINFOHEADER; // 像素结构体 typedef struct { unsigned char b; // 蓝色分量 unsigned char g; // 绿色分量 unsigned char r; // 红色分量 unsigned char a; // Alpha分量 } PIXEL; int main() { char bmpFileName[256]; // BMP文件名 printf("请输入BMP文件名:"); scanf("%s", bmpFileName); FILE* bmpFile = fopen(bmpFileName, "rb"); // 以二进制只读方式打开BMP文件 if (!bmpFile) { printf("打开BMP文件失败!\n"); return 0; } BMPFILEHEADER fileHeader; BMPINFOHEADER infoHeader; // 读取BMP文件头和信息头 fread(&fileHeader, sizeof(BMPFILEHEADER), 1, bmpFile); fread(&infoHeader, sizeof(BMPINFOHEADER), 1, bmpFile); // 检查BMP文件是否合法 if (strncmp(fileHeader.bfType, "BM", 2) != 0 || infoHeader.biBitCount != 32) { printf("不支持的BMP文件格式!\n"); fclose(bmpFile); return 0; } // 计算每行像素所占的字节数 int rowSize = ((infoHeader.biWidth * infoHeader.biBitCount + 31) / 32) * 4; // 分配像素数组内存 PIXEL* pixels = (PIXEL*)malloc(infoHeader.biHeight * rowSize); // 读取像素数据 fseek(bmpFile, fileHeader.bfOffBits, SEEK_SET); fread(pixels, infoHeader.biHeight * rowSize, 1, bmpFile); // 关闭BMP文件 fclose(bmpFile); // 分别保存四个分量的数组和文件名 unsigned char* aArray = (unsigned char*)malloc(infoHeader.biWidth * infoHeader.biHeight); unsigned char* rArray = (unsigned char*)malloc(infoHeader.biWidth * infoHeader.biHeight); unsigned char* gArray = (unsigned char*)malloc(infoHeader.biWidth * infoHeader.biHeight); unsigned char* bArray = (unsigned char*)malloc(infoHeader.biWidth * infoHeader.biHeight); char aFileName[256], rFileName[256], gFileName[256], bFileName[256]; sprintf(aFileName, "%s_a.txt", bmpFileName); sprintf(rFileName, "%s_r.txt", bmpFileName); sprintf(gFileName, "%s_g.txt", bmpFileName); sprintf(bFileName, "%s_b.txt", bmpFileName); // 提取每个像素的四个分量,并保存到对应的数组中 for (int y = 0; y < infoHeader.biHeight; y++) { for (int x = 0; x < infoHeader.biWidth; x++) { PIXEL* pixel = &pixels[y * rowSize / 4 + x]; aArray[y * infoHeader.biWidth + x] = pixel->a; rArray[y * infoHeader.biWidth + x] = pixel->r; gArray[y * infoHeader.biWidth + x] = pixel->g; bArray[y * infoHeader.biWidth + x] = pixel->b; } } // 打开四个txt文件并将分量数组中的数据写入 FILE* aFile = fopen(aFileName, "w"); FILE* rFile = fopen(rFileName, "w"); FILE* gFile = fopen(gFileName, "w"); FILE* bFile = fopen(bFileName, "w"); for (int y = 0; y < infoHeader.biHeight; y++) { for (int x = 0; x < infoHeader.biWidth; x++) { fprintf(aFile, "%d,", aArray[y * infoHeader.biWidth + x]); fprintf(rFile, "%d,", rArray[y * infoHeader.biWidth + x]); fprintf(gFile, "%d,", gArray[y * infoHeader.biWidth + x]); fprintf(bFile, "%d,", bArray[y * infoHeader.biWidth + x]); if (x == infoHeader.biWidth - 1) { fprintf(aFile, "\n"); fprintf(rFile, "\n"); fprintf(gFile, "\n"); fprintf(bFile, "\n"); } } } // 关闭四个txt文件 fclose(aFile); fclose(rFile); fclose(gFile); fclose(bFile); // 释放内存 free(pixels); free(aArray); free(rArray); free(gArray); free(bArray); printf("分量已保存到%s_a.txt、%s_r.txt、%s_g.txt、%s_b.txt中!\n", bmpFileName, bmpFileName, bmpFileName, bmpFileName); return 0; } ``` 该代码可以读取指定的BMP文件,提取每个像素的四个分量,并分别保存到四个txt文件中。每个数以逗号隔开,每在txt文件中打印满一行像素,就换行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值