`
jimmee
  • 浏览: 529799 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

c内存操作感悟(1)

阅读更多

直接使用c, 有个好处, 自己可以完全控制内存啊,一切脑海中记住内存及指针, 就很容易知道操作是怎样.

 

1. 分配一段内存, 这段内存使用什么样的指针操作, 那么对应就是多少字节的操作, 也就是说, 看你怎么去解释

这块内存了.

 

例如, 若分配给一个10个字节的类型, 如果用一个int类型的指针指向这块内存, 那么一次操作, 就是int的字节的大小, 如果一个struct指向这块内存, 那么一次操作就是针对这个struct的内存的大小, 如果是一个数组指向这块内存,  那么就是连续的这个数组的元素类型的字节了.

 

2. 怎么改变内存中指针的指向, 进行指针的加减就行了, 但是指针加减,  这个和指针的类型有关系的.

 

 

#include <stdio.h>
#include <stdlib.h>

typedef struct {
	int i;
	char c;
} tag;

int main(void) {
	tag *t = (tag *)malloc(20);
	tag *t2 = t+1;
	printf("%d\n", sizeof(tag));
	printf("%p\n", t);
	printf("%p\n",t2);
	return EXIT_SUCCESS;
}

 

 

上述代码的打印结果:

8

001A3D10

 

001A3D18

 

3. struct存在对齐问题, 所以上述示例的的struct的实际大小不是5, 而是8

 

4.  怎么实现变长数组? 示例:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
	int i;
	char c[0];
} tag;

int main(void) {
	tag *t = (tag *)malloc(13);
	printf("%d\n", sizeof(tag));
	t->i=4;
	memcpy(t->c,"hijimmee", 8);
	t->c[8]='\0';
	printf("%s\n",t->c);

	free(t);
	return EXIT_SUCCESS;
}

 

   更具体的例子:

 

#include <stdlib.h>
#include <stdio.h>

typedef unsigned long     cell;

/* INSTANCE */
struct instanceStruct {

    // 这里的数组仅仅是占位, data[]数组不仅仅只有一个元素, 可以使用更大的index值来存取
    // data[1]之后的元素值
    union {
        cell *cellp;
        cell cell;
    } data[1];
};

struct instance {
	int num;
	int arr[2];
};

int main(void) {
	int size = sizeof(cell) * 3;
	printf("%d\n", size);

	printf("%lu\n", sizeof(instanceStruct));

	instanceStruct *ins = (instanceStruct *) malloc(size);
	cell *c = (cell *)malloc(sizeof(cell));
	ins->data[0].cell = 5;
	ins->data[1].cell = 15;
	ins->data[2].cell = 155;
	*c = 157;
	printf("%lu,%lu,%lu, %lu\n", ins->data[0].cell, ins->data[1].cell, ins->data[2].cell);

	printf("%d\n", sizeof(instance));

	instance *s = (instance *) malloc(sizeof(instance) * 2);
	s->num = 1;
	s->arr[0] = 2;
	s->arr[1] = 3;
	instance *first = s;
	s++;
	s->num = 4;
	s->arr[1] = 5;
	s->arr[2] = 6;
	printf("%d, %d, %d\n", first->num, first->arr[0], first->arr[1]);
	printf("%d, %d, %d\n", s->num, s->arr[0], s->arr[1]);
	// 这里可以看到,实际上不管是否数组是否越界了,永远根据指针类型进行访问
	printf("overflow access: %d\n", first->arr[2]);
}

   我64位的机器,输出结果如下:

  

24
8
5,15,155, 12
12
1, 2, 3
4, 13, 5
overflow access: 4

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics