array class, please comment

ment to be simple, you can use it as an normal array or as an simple vector (which I tend to use alot)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//Simple array, if AllocSizeInBytes is less than sizeof(T), than it will resize with each entry only as much as it has to
template <class T, unsigned AllocSize=128>
class vector{
private:
	T*					buf;
	unsigned			current;
	unsigned			max;
	unsigned			alloc;

	void				resize(unsigned size=1){
		unsigned n;
		size=size-(max+current);
		if(alloc){
			n=(size/alloc);
			if(size%alloc!=0)
				n++;
		}
		T* tmp = buf;
		tmp=(T*)realloc(tmp, max+n);
		if(!tmp){
			tmp=(T*)malloc(sizeof(T)*max+n);
			memcpy(tmp, buf, current*sizeof(T));
			free(buf);
		}
		max=max+n;
	};
public:
	operator T*(){//acts as an array sized size()
		return buf;
	}
	T operator [](unsigned index){
		return buf+index;
	};
	vector& push(T value){
		if(current=max)
			resize();
		memcpy((void*)buf+current-1, (void*)value, sizeof(T));
		current+=1;
		return this;
	};//Single element
	vector& push(const T* value, unsigned size){
		if(current+size>max)
			resize(size);
		memcpy((void*)buf+current-1, (void*)value, size*sizeof(T));
		current+=size;
		return this;
	};//You can push of size Bytes, just specify the size parameter
	vector& push(const T* value){
		unsigned i=0, j; unsigned char *tmp=(unsigned char*)value;
		do{
			while(tmp[i++]!=0);
			if(i%(sizeof(T)/sizeof(unsigned char))==0){
				j=i;
				while(tmp[++i]==0);
				if(i-j==sizeof(T)/sizeof(unsigned char))
					goto pdone;
			}
			i=j;
		}while(true);
pdone:
		i=i/(sizeof(T)/sizeof(unsigned char));
		if(current+i>max)
			resize(i);
		memcpy((void*)buf+current-1, (void*)value, i*sizeof(T));
		current+=i;
		return this;
	};//Null ended array
	unsigned			last(){
		return current-1;
	}
	unsigned			size(){
		return current;
	}
	unsigned			allocated(){
		return max;
	}
	vector& setAllocSize(unsigned as){
		alloc=as;
		return this;
	}
	unsigned		getAllocSize(){
		return alloc;
	}

	vector(){
		alloc=AllocSize;
		buf=(T*)malloc(sizeof(T)*alloc);
		current=0;
		max=alloc;
	};
	vector(const T* data){
		alloc=AllocSize;

		unsigned i=0, j; unsigned char *tmp=(unsigned char*)value;
		do{
			while(tmp[i++]!=0);
			if(i%(sizeof(T)/sizeof(unsigned char))==0){
				j=i;
				while(tmp[++i]==0);
				if(i-j==sizeof(T)/sizeof(unsigned char))
					goto vdone;
			}
			i=j;
		}while(true);
vdone:
		i=i/(sizeof(T)/sizeof(unsigned char));
		buf=(T*)malloc(sizeof(T)*alloc);
		max=alloc;
		memcpy((void*)buf+current-1, (void*)value, i*sizeof(T));
		current=i;
	};//Null terminated array
	vector(const T* data, unsigned size){
		alloc=AllocSize;
		unsigned n;
		if(alloc){
			n=size/alloc;
			if(size%alloc!=0)
				n++;
		} else
			n=size;
		buf=(T*)malloc(sizeof(T)*n);
		current=0;
		max=alloc;
		memcpy((void*)buf+current-1, (void*)value, size*sizeof(T));
		current+=size;
	};//Normal array w/ n elements
	~vector(){
		free(buf);	
	};
};

PS include stdio
Last edited on
1. goto pdone?
2. How do you create one on a custom heap?
3. How do you use it with STL algorithms?
4. Realloc. What if it gives you a new block?
5. No check for malloc failure.
6. Doesn't work with non-builtin types.
7. Push scalar passed by value, push array passed by const ref.
8. last not one passed the end, so can't be used to check for empty.
line 31:
1
2
3
	T operator [](unsigned index){
		return buf+index;
	};

return type is T, but you're returning T*
change to return buf[index]; or return *(buf+index);

In a bunch of other functions the return type is vector& but you're returning vector* (because you're returning this). You probably meant to return *this;


Since you're using memcpy, this will fail catastrophically if used with complex types that have custom ctors/dtors. So pretty much that limits its usage only to basic types.

AllocSize as a template argument doesn't make any sense, and will make types which should be compatible incompatible. Just give a ctor a default value.

You need to write your own copy ctor and assignment operator. The default ones will not work because you are maintaining a pointer. As your class is currently, if you try to copy or reassign a vector, it will cause the same buffer to be free'd twice.


Also I have to ask... any reason you can't just use std::vector? Or was this something you did as practice to see if you could do it?


edit: + what kbw said
Last edited on
fail'd :D

Thanks


Disch: yhe, I tought I knew how to write a simple container, c++ style

Edit:
after going thru it 1 more time I see I dont understand references and some concepts of good overloading as you pointed out...will work on than

back to std::vector 4 now
Last edited on
Topic archived. No new replies allowed.