首页
社区
课程
招聘
请教个vc编译器赋初值的问题
发表于: 2011-5-18 11:29 8359

请教个vc编译器赋初值的问题

2011-5-18 11:29
8359
typedef struct tagList {
        char Str[33];
}myList, *pmyList;

tagList p[1000];

如何在编译的时候就给这 1000个p里面的Str指定初值?比如,指定1000个p.str="1222222"
必须把这1000个的初值编译到exe里面,程序执行期间动态赋值不行.应该怎么写呢?

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (17)
雪    币: 214
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我写了两个宏来实现lz的要求,不知lz是不是要这样。

#define TEN_TIMES(str) str,str,str,str,str,str,str,str,str,str
#define THOUSAND_TIMES(str)   TEN_TIMES(TEN_TIMES(TEN_TIMES(str)))

int main()
{
        myList list[1000] ={THOUSAND_TIMES("122222222")};

        return 0;
}
2011-5-18 12:27
0
雪    币: 43
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
预留空间,然后修改PE文件。
2011-5-18 12:38
0
雪    币: 40
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
lsls,宏定义的方法好像不对要求
2011-5-18 21:36
0
雪    币: 214
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
哦?那你觉得要求是什么?
2011-5-18 22:23
0
雪    币: 201
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
char szBuf[MAX_PATH * 100] = { 0 };
没有问题
2011-5-19 11:01
0
雪    币: 214
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
[QUOTE=善良屠夫;960447]char szBuf[MAX_PATH * 100] = { 0 };
没有问题[/QUOTE]
不要想当然,这个错误大概是最常见的一个错误了,你给出的情况刚好是特殊的那种,而lz提到的不是这种特殊情况。

char buffer[10] = {'1'}这样初始化事实上只初始化了第一个单元——buffer[0]是'1',但是buffer[1]到buffer[9]全部是0,编译器认为是这样的:
char buffer[10] = {'1',0,0,0,0,0,0,0,0,0};
2011-5-19 11:32
0
雪    币: 12
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
用全局或静态变量,数组自动赋初值0.
2011-7-14 16:37
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
2L的方法应该是正确的,根据LZ要求进行了小改动,以下是测试程序,gcc编译通过。

//=====================================
#include "stdio.h"
#include "stdlib.h"

#define TEN_TIMES(str) str,str,str,str,str,str,str,str,str,str
#define K_TIMES(str)   TEN_TIMES(TEN_TIMES(TEN_TIMES(str)))

typedef struct tagList
{
    char Str[33];
}myList, *pmyList;

int main()
{
    int i;
    tagList p[1000]={K_TIMES({"122222222"})}; //这里注意要有{},因为是给结构体的Str成员赋初值
  
    for(i=0;i<=1000-1;i++)  //用于测试的循环,输出赋值情况
    {
        printf("%5d %s\n",i,p[i].Str);
    }
   
    system("pause");
   
    return 0;
}
//===================================
2011-7-15 00:36
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
上述程序编译时会自动被优化,将编译连接后的可执行文件反汇编发现:

程序中从00402000h~0040AFFF是程序数据区段。内容是33字节的结构体{"122222222"}重复1000次,然后后面补零。

执行部分是是调用memcpy函数复制以上33*1000字节的内容到实际结构体所在的内存中(起始于00227e70h)。

即相当于调用:memcpy(00227e70h,00402000h,33*1000);

至此完成初始化过程的赋值操作(结构体数组赋初值)。
2011-7-15 01:21
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
刚才在10L里写的是gcc编译器在标准优化下的程序调试结果。

在VC Release的编译连接结果中发现了更加变态的优化。。= =
vc编译出来的数据区段里只有33字节的结构体{"122222222"},没有重复...
而程序区段中是长达几百来页的mov语句(00401000h-004128FBh)。。。
(默认优化执行速度?)
===================
这意味着什么呢? 意味着哪怕写程序的时候代码的意思是在变量、数组、结构体初始化过程中进行赋值了,但是在不同的编译环境下(编译器不同,优化开关不同-速度/大小),编译的实际结果仍然可能和代码的初衷相左。

所以如果LZ实在要达到以上帖子中描述的目的,还需要设置好编译器的优化选项。

附:
大段mov语句一瞥
...
00401030  |.  895424 22     mov     dword ptr [esp+22], edx
00401034  |.  894424 08     mov     dword ptr [esp+8], eax
00401038  |.  66:895424 26  mov     word ptr [esp+26], dx
0040103D  |.  894C24 0C     mov     dword ptr [esp+C], ecx
00401041  |.  885424 28     mov     byte ptr [esp+28], dl
00401045  |.  895424 33     mov     dword ptr [esp+33], edx
00401049  |.  895424 37     mov     dword ptr [esp+37], edx
0040104D  |.  66:897424 10  mov     word ptr [esp+10], si
00401052  |.  895424 3B     mov     dword ptr [esp+3B], edx
00401056  |.  894424 29     mov     dword ptr [esp+29], eax
0040105A  |.  895424 3F     mov     dword ptr [esp+3F], edx
0040105E  |.  894C24 2D     mov     dword ptr [esp+2D], ecx
00401062  |.  895424 43     mov     dword ptr [esp+43], edx
...
即使用了以下寄存器存储结构体的内容然后循环使用来赋值:eax=32323231h,ecx=32323232h,edx=00000000h(则dx=0000h,dl=00h),esi=ffff0032(即si=0032)
2011-7-15 01:52
0
雪    币: 23
活跃值: (31)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
这个有优化,
还是想办法留出空间,找到变量的偏移,手工改pe文件吧
2011-7-15 05:22
0
雪    币: 156
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
这种的行吗? ->http://zhidao.baidu.com/question/36153993
2011-7-17 09:24
0
雪    币: 77
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
大家想的复杂了吧。
typedef struct tagList {
  char Str[33];
}myList, *pmyList;

tagList p[1000];

for(int i=0;i<1000;i++)
{

strcpy(p[i].Str,"122222222");

}
VC6.0编译通过。
2011-7-20 15:56
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
[QUOTE=grantcz;982715]大家想的复杂了吧。
typedef struct tagList {
  char Str[33];
}myList, *pmyList;

tagList p[1000];

for(int i=0;i<1000;i++)
{

strcpy(p[i].Str,&q...[/QUOTE]
人家LZ不要动态赋值....
2011-7-20 16:56
0
雪    币: 377
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
GVU
16
2楼的方法不错,但是如果是1001或者其他大小呢??
2011-7-21 10:32
0
雪    币: 77
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
看来还得继续定义一个加减法的宏
以后可以继续扩展到乘除法
lz的这个问题真是经典啊,哈哈。
2011-7-21 10:55
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
学习了!!!!!
2011-7-21 13:24
0
游客
登录 | 注册 方可回帖
返回
//