CHNOSProjectのすべてのプロジェクトのソースのルート
修订版 | ffb73332f17338f77ba58e14dadd13dcf9df4cfa (tree) |
---|---|
时间 | 2013-05-19 06:22:03 |
作者 | hikarupsp <hikarupsp@user...> |
Commiter | hikarupsp |
referenceCountを導入。今のところ正常に動作している。メモリリークについても一部改善。69.67KB(1852/2023)>36.59KB(588/2163)
@@ -86,11 +86,11 @@ | ||
86 | 86 | ignoreCount = "0" |
87 | 87 | continueAfterRunningActions = "No" |
88 | 88 | filePath = "AI003/main.c" |
89 | - timestampString = "390425099.955042" | |
89 | + timestampString = "390602565.100723" | |
90 | 90 | startingColumnNumber = "9223372036854775807" |
91 | 91 | endingColumnNumber = "9223372036854775807" |
92 | - startingLineNumber = "272" | |
93 | - endingLineNumber = "272" | |
92 | + startingLineNumber = "280" | |
93 | + endingLineNumber = "280" | |
94 | 94 | landmarkName = "AI_Memory_AddRootWordData()" |
95 | 95 | landmarkType = "7"> |
96 | 96 | </FileBreakpoint> |
@@ -175,11 +175,11 @@ | ||
175 | 175 | ignoreCount = "0" |
176 | 176 | continueAfterRunningActions = "No" |
177 | 177 | filePath = "AI003/main.c" |
178 | - timestampString = "390425099.955042" | |
178 | + timestampString = "390602565.100723" | |
179 | 179 | startingColumnNumber = "9223372036854775807" |
180 | 180 | endingColumnNumber = "9223372036854775807" |
181 | - startingLineNumber = "107" | |
182 | - endingLineNumber = "107" | |
181 | + startingLineNumber = "119" | |
182 | + endingLineNumber = "119" | |
183 | 183 | landmarkName = "AI_Think_LearnWordFromInputString()" |
184 | 184 | landmarkType = "7"> |
185 | 185 | </FileBreakpoint> |
@@ -188,11 +188,11 @@ | ||
188 | 188 | ignoreCount = "0" |
189 | 189 | continueAfterRunningActions = "No" |
190 | 190 | filePath = "AI003/main.c" |
191 | - timestampString = "390425099.955042" | |
191 | + timestampString = "390602565.100723" | |
192 | 192 | startingColumnNumber = "9223372036854775807" |
193 | 193 | endingColumnNumber = "9223372036854775807" |
194 | - startingLineNumber = "123" | |
195 | - endingLineNumber = "123" | |
194 | + startingLineNumber = "136" | |
195 | + endingLineNumber = "136" | |
196 | 196 | landmarkName = "AI_Think_LearnWordFromInputString()" |
197 | 197 | landmarkType = "7"> |
198 | 198 | </FileBreakpoint> |
@@ -201,11 +201,11 @@ | ||
201 | 201 | ignoreCount = "0" |
202 | 202 | continueAfterRunningActions = "No" |
203 | 203 | filePath = "AI003/main.c" |
204 | - timestampString = "390425099.955042" | |
204 | + timestampString = "390602565.100723" | |
205 | 205 | startingColumnNumber = "9223372036854775807" |
206 | 206 | endingColumnNumber = "9223372036854775807" |
207 | - startingLineNumber = "128" | |
208 | - endingLineNumber = "128" | |
207 | + startingLineNumber = "129" | |
208 | + endingLineNumber = "129" | |
209 | 209 | landmarkName = "AI_Think_LearnWordFromInputString()" |
210 | 210 | landmarkType = "7"> |
211 | 211 | </FileBreakpoint> |
@@ -214,11 +214,11 @@ | ||
214 | 214 | ignoreCount = "0" |
215 | 215 | continueAfterRunningActions = "No" |
216 | 216 | filePath = "AI003/main.c" |
217 | - timestampString = "390473631.009346" | |
217 | + timestampString = "390602565.100723" | |
218 | 218 | startingColumnNumber = "9223372036854775807" |
219 | 219 | endingColumnNumber = "9223372036854775807" |
220 | - startingLineNumber = "117" | |
221 | - endingLineNumber = "117" | |
220 | + startingLineNumber = "120" | |
221 | + endingLineNumber = "120" | |
222 | 222 | landmarkName = "AI_Think_LearnWordFromInputString()" |
223 | 223 | landmarkType = "7"> |
224 | 224 | </FileBreakpoint> |
@@ -227,24 +227,11 @@ | ||
227 | 227 | ignoreCount = "0" |
228 | 228 | continueAfterRunningActions = "No" |
229 | 229 | filePath = "AI003/main.c" |
230 | - timestampString = "390473685.266823" | |
230 | + timestampString = "390602565.100723" | |
231 | 231 | startingColumnNumber = "9223372036854775807" |
232 | 232 | endingColumnNumber = "9223372036854775807" |
233 | - startingLineNumber = "108" | |
234 | - endingLineNumber = "108" | |
235 | - landmarkName = "AI_Think_LearnWordFromInputString()" | |
236 | - landmarkType = "7"> | |
237 | - </FileBreakpoint> | |
238 | - <FileBreakpoint | |
239 | - shouldBeEnabled = "No" | |
240 | - ignoreCount = "0" | |
241 | - continueAfterRunningActions = "No" | |
242 | - filePath = "AI003/main.c" | |
243 | - timestampString = "390473859.806502" | |
244 | - startingColumnNumber = "9223372036854775807" | |
245 | - endingColumnNumber = "9223372036854775807" | |
246 | - startingLineNumber = "178" | |
247 | - endingLineNumber = "178" | |
233 | + startingLineNumber = "186" | |
234 | + endingLineNumber = "186" | |
248 | 235 | landmarkName = "AI_Think_SlideLookUpWordByHistory()" |
249 | 236 | landmarkType = "7"> |
250 | 237 | </FileBreakpoint> |
@@ -253,11 +240,11 @@ | ||
253 | 240 | ignoreCount = "0" |
254 | 241 | continueAfterRunningActions = "No" |
255 | 242 | filePath = "AI003/main.c" |
256 | - timestampString = "390474101.310759" | |
243 | + timestampString = "390602565.100723" | |
257 | 244 | startingColumnNumber = "9223372036854775807" |
258 | 245 | endingColumnNumber = "9223372036854775807" |
259 | - startingLineNumber = "184" | |
260 | - endingLineNumber = "184" | |
246 | + startingLineNumber = "192" | |
247 | + endingLineNumber = "192" | |
261 | 248 | landmarkName = "AI_Think_SlideLookUpWordByHistory()" |
262 | 249 | landmarkType = "7"> |
263 | 250 | </FileBreakpoint> |
@@ -12,6 +12,7 @@ | ||
12 | 12 | #include "chnlib.h" |
13 | 13 | |
14 | 14 | #define AI_CONFIG_FILE_NAME "config.txt" |
15 | +#define AI_INPUT_HISTORY_MAX 10 | |
15 | 16 | |
16 | 17 | typedef struct AI_WORKING_SET AI_WorkingSet; |
17 | 18 | struct AI_WORKING_SET { |
@@ -64,12 +64,13 @@ int main(int argc, const char * argv[]) | ||
64 | 64 | } else if(CHNLIB_String_CompareStringWithCString(temp, "exit")){ |
65 | 65 | break; |
66 | 66 | } else if(CHNLIB_String_CompareStringWithCString(temp, "wordlist")){ |
67 | - sorted = CHNLIB_UIPArray_SortInDescendingOrderByData32(WorkingSet.RootWordList); | |
67 | + sorted = CHNLIB_UIPArray_GetSortedInDescendingOrderByData32(WorkingSet.RootWordList); | |
68 | 68 | i_max = CHNLIB_UIPArray_GetNumberOfDatas(sorted); |
69 | 69 | for(i = 0; i < i_max; i++){ |
70 | 70 | printf("word%3d:%3d:%s\n", i, CHNLIB_UIPArray_GetData32ByIndex(sorted, i), CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(sorted, i))); |
71 | 71 | } |
72 | - CHNLIB_UIPArray_FreeOnlyArray(&sorted); | |
72 | + //CHNLIB_UIPArray_FreeOnlyArray(&sorted); | |
73 | + release(sorted); | |
73 | 74 | } else if(CHNLIB_String_CompareStringWithCString(temp, "readfile")){ |
74 | 75 | //::readfile:filename |
75 | 76 | readfp = fopen(CHNLIB_String_GetReferencePointerOfCString(CHNLIB_UIPArray_GetPointerByIndex(separated, 4)), "rb"); |
@@ -81,8 +82,9 @@ int main(int argc, const char * argv[]) | ||
81 | 82 | } |
82 | 83 | } |
83 | 84 | |
84 | - //WorkingSet.SystemWordList0を使っているので、解放しないように注意 | |
85 | - CHNLIB_UIPArray_FreeSelectedAll(&separated); | |
85 | + ////WorkingSet.SystemWordList0を使っているので、解放しないように注意 | |
86 | + //CHNLIB_UIPArray_FreeSelectedAll(&separated); | |
87 | + release(separated); | |
86 | 88 | } |
87 | 89 | |
88 | 90 | if(!passthink){ |
@@ -90,8 +92,17 @@ int main(int argc, const char * argv[]) | ||
90 | 92 | //::readfile:AITestData_ja.txt |
91 | 93 | AI_Think_LearnWordFromInputString(input); |
92 | 94 | |
93 | - CHNLIB_UIPArray_AppendLast(&WorkingSet.InputHistory, CHNLIB_UIPArray_GetNumberOfDatas(WorkingSet.InputHistory), input); | |
95 | + //入力履歴を追加 | |
96 | + i = CHNLIB_UIPArray_AppendLast(&WorkingSet.InputHistory, 0, input); | |
97 | + if(i > AI_INPUT_HISTORY_MAX){ | |
98 | + //履歴の整理 | |
99 | + for(i = 0; i < AI_INPUT_HISTORY_MAX; i++){ | |
100 | + CHNLIB_UIPArray_RemoveByIndex(&WorkingSet.InputHistory, 0); | |
101 | + } | |
102 | + } | |
94 | 103 | } |
104 | + | |
105 | + release(input); | |
95 | 106 | } |
96 | 107 | |
97 | 108 | return 0; |
@@ -117,15 +128,11 @@ void AI_Think_LearnWordFromInputString(CHNLIB_String *input) | ||
117 | 128 | tagIndex = AI_Memory_AddRootWordData(CHNLIB_UIPArray_GetPointerByIndex(candidateWordList, i)); |
118 | 129 | |
119 | 130 | CHNLIB_UIPArray_SetData32ByIndex(WorkingSet.RootWordList, tagIndex, CHNLIB_UIPArray_GetData32ByIndex(WorkingSet.RootWordList, tagIndex) + CHNLIB_UIPArray_GetData32ByIndex(candidateWordList, i)); |
120 | - | |
121 | - if(tagIndex <= maxExistingWordIndex){ | |
122 | - //既存のタグなので、解放されるようにdata32をFalseにしておく。 | |
123 | - CHNLIB_UIPArray_SetData32ByIndex(candidateWordList, i, False); | |
124 | - } | |
125 | - //新規追加されたタグについては0以上の値つまりTrueが設定されているはずなので、解放されない。 | |
126 | 131 | } |
127 | - //data32 == Falseのタグ、つまり既存のタグと同じだったもののみ解放する。 | |
128 | - CHNLIB_UIPArray_FreeSelectedAll(&candidateWordList); | |
132 | + //すでに存在したタグは追加されていないため、ReferenceCountが1のはずなので、解放される。 | |
133 | + //追加されたタグはReferenceCountが2のため、解放されない。 | |
134 | + release(candidateWordList); | |
135 | + //CHNLIB_UIPArray_FreeSelectedAll(&candidateWordList); | |
129 | 136 | |
130 | 137 | return; |
131 | 138 | } |
@@ -175,7 +182,7 @@ CHNLIB_UIPArray *AI_Think_SlideLookUpWordByHistory(CHNLIB_String *input) | ||
175 | 182 | } |
176 | 183 | } |
177 | 184 | if(candidatelength > 0){ |
178 | - CHNLIB_UIPArray_AppendLast_ProtectFromDuplication(&candidatewordlist, 0, CHNLIB_String_ExtractByLength(input, CHNLIB_UTF8_GetByteSizeFromLengthByCharacter(cstr_input, 0, k - 1), CHNLIB_UTF8_GetByteSizeFromLengthByCharacter(cstrp_input, 0, candidatelength - 1)), &AI_Memory_AddRootWordData_IsDuplicated); | |
185 | + CHNLIB_UIPArray_AppendLast_ProtectFromDuplication(&candidatewordlist, 0, autorelease(CHNLIB_String_ExtractByLength(input, CHNLIB_UTF8_GetByteSizeFromLengthByCharacter(cstr_input, 0, k - 1), CHNLIB_UTF8_GetByteSizeFromLengthByCharacter(cstrp_input, 0, candidatelength - 1))), &AI_Memory_AddRootWordData_IsDuplicated); | |
179 | 186 | } |
180 | 187 | CHNLIB_UTF8_GetNextUnicodeOfCharacter(cstrp_input, &cstrp_input); |
181 | 188 | } |
@@ -290,8 +297,8 @@ void AI_System_InitializeSystemWorkingSet(void) | ||
290 | 297 | { |
291 | 298 | //WorkingSetを初期化する。 |
292 | 299 | WorkingSet.SystemWordList0 = CHNLIB_UIPArray_Initialize(); |
293 | - CHNLIB_UIPArray_AppendLast(&WorkingSet.SystemWordList0, True, CHNLIB_String_Initialize(":")); | |
294 | - CHNLIB_UIPArray_AppendLast(&WorkingSet.SystemWordList0, True, CHNLIB_String_Initialize(",")); | |
300 | + CHNLIB_UIPArray_AppendLast(&WorkingSet.SystemWordList0, True, autorelease(CHNLIB_String_Initialize(":"))); | |
301 | + CHNLIB_UIPArray_AppendLast(&WorkingSet.SystemWordList0, True, autorelease(CHNLIB_String_Initialize(","))); | |
295 | 302 | |
296 | 303 | WorkingSet.InputHistory = CHNLIB_UIPArray_Initialize(); |
297 | 304 |
@@ -310,6 +317,7 @@ void AI_System_LoadMemory(const char configfilename[]) | ||
310 | 317 | fclose(fp); |
311 | 318 | |
312 | 319 | fp = fopen(CHNLIB_String_GetReferencePointerOfCString(currentfilename), "rb"); |
320 | + release(currentfilename); | |
313 | 321 | |
314 | 322 | WorkingSet.RootWordList = CHNLIB_UIPArray_Initialize(); |
315 | 323 | for(i = 1; ;i++){ |
@@ -318,12 +326,9 @@ void AI_System_LoadMemory(const char configfilename[]) | ||
318 | 326 | break; |
319 | 327 | } |
320 | 328 | CHNLIB_UIPArray_AppendLast(&WorkingSet.RootWordList, i, line); |
321 | - //CHNLIB_String_Free(line);リストに登録している実体なので解放の必要なし! | |
329 | + release(line); | |
322 | 330 | } |
323 | 331 | fclose(fp); |
324 | - CHNLIB_String_Free(currentfilename); | |
325 | - | |
326 | - //CHNLIB_Debug_PrintStructureData(WorkingSet.RootWordList, 0); | |
327 | 332 | |
328 | 333 | return; |
329 | 334 | } |
@@ -60,11 +60,11 @@ | ||
60 | 60 | ignoreCount = "0" |
61 | 61 | continueAfterRunningActions = "No" |
62 | 62 | filePath = "chn/chnlib.h" |
63 | - timestampString = "384873562.138536" | |
63 | + timestampString = "390601441.205558" | |
64 | 64 | startingColumnNumber = "9223372036854775807" |
65 | 65 | endingColumnNumber = "9223372036854775807" |
66 | - startingLineNumber = "118" | |
67 | - endingLineNumber = "118"> | |
66 | + startingLineNumber = "119" | |
67 | + endingLineNumber = "119"> | |
68 | 68 | </FileBreakpoint> |
69 | 69 | <FileBreakpoint |
70 | 70 | shouldBeEnabled = "No" |
@@ -92,5 +92,18 @@ | ||
92 | 92 | landmarkName = "calc_value0()" |
93 | 93 | landmarkType = "7"> |
94 | 94 | </FileBreakpoint> |
95 | + <FileBreakpoint | |
96 | + shouldBeEnabled = "No" | |
97 | + ignoreCount = "0" | |
98 | + continueAfterRunningActions = "No" | |
99 | + filePath = "libtest/libtest/main.c" | |
100 | + timestampString = "390597364.50073" | |
101 | + startingColumnNumber = "9223372036854775807" | |
102 | + endingColumnNumber = "9223372036854775807" | |
103 | + startingLineNumber = "28" | |
104 | + endingLineNumber = "28" | |
105 | + landmarkName = "main()" | |
106 | + landmarkType = "7"> | |
107 | + </FileBreakpoint> | |
95 | 108 | </FileBreakpoints> |
96 | 109 | </Bucket> |
@@ -95,6 +95,7 @@ void CHNLIB_StructureHeader_Initialize(CHNLIB_StructureHeader *header, uint type | ||
95 | 95 | { |
96 | 96 | //ライブラリ共通構造体ヘッダの初期化を行う。 |
97 | 97 | //各構造体のInitializeで呼ばれることを想定している。 |
98 | + //referenceCountは1で初期化される(初期化を行った関数が所有すると考える) | |
98 | 99 | if(header == NULL){ |
99 | 100 | CHNLIB_ReportError("Null structure.", CHNLIB_DEBUG_ARGUMENTS); |
100 | 101 | return; |
@@ -102,6 +103,11 @@ void CHNLIB_StructureHeader_Initialize(CHNLIB_StructureHeader *header, uint type | ||
102 | 103 | |
103 | 104 | header->signature = CHNLIB_STRUCTURE_SIGNATURE; |
104 | 105 | header->typeid = typeid; |
106 | +#ifdef DEBUG_MEMORY_REFERENCE_COUNT | |
107 | + CHNLIB_Debug("Init with referenceCount = 1 [%p].", CHNLIB_DEBUG_ARGUMENTS, header); | |
108 | +#endif | |
109 | + header->referenceCount = 1; | |
110 | + header->destructor = NULL; | |
105 | 111 | return; |
106 | 112 | } |
107 | 113 |
@@ -160,6 +166,83 @@ void CHNLIB_System_FreeMemory(void *p, const char filename[], int line, const ch | ||
160 | 166 | return; |
161 | 167 | } |
162 | 168 | |
169 | +void CHNLIB_Retain(void **structure) | |
170 | +{ | |
171 | + //structureのreferenceCountをインクリメントする。 | |
172 | + //referenceCountの初期値は1 | |
173 | + | |
174 | + CHNLIB_StructureHeader *strhead; | |
175 | + | |
176 | + if(structure == NULL || *structure == NULL){ | |
177 | + return; | |
178 | + } | |
179 | + | |
180 | + strhead = (CHNLIB_StructureHeader *)*structure; | |
181 | + if(strhead->signature == CHNLIB_STRUCTURE_SIGNATURE){ | |
182 | +#ifdef DEBUG_MEMORY_REFERENCE_COUNT | |
183 | + CHNLIB_Debug("Retain [%p].", CHNLIB_DEBUG_ARGUMENTS, *structure); | |
184 | +#endif | |
185 | + strhead->referenceCount++; | |
186 | + } | |
187 | + | |
188 | + return; | |
189 | +} | |
190 | + | |
191 | +void CHNLIB_Release(void **structure) | |
192 | +{ | |
193 | + //structureのreferenceCountをデクリメントする。 | |
194 | + //デクリメントした結果referenceCount==0となった時、そのstructureを解放する。 | |
195 | + //structureが内包しているオブジェクトについては、releaseを行う。 | |
196 | + | |
197 | + CHNLIB_StructureHeader *strhead; | |
198 | + | |
199 | + if(structure == NULL || *structure == NULL){ | |
200 | + return; | |
201 | + } | |
202 | + | |
203 | + strhead = (CHNLIB_StructureHeader *)*structure; | |
204 | + if(strhead->signature == CHNLIB_STRUCTURE_SIGNATURE){ | |
205 | + if(strhead->referenceCount <= 1){ | |
206 | + if(strhead->destructor == NULL){ | |
207 | +#ifdef DEBUG_MEMORY_REFERENCE_COUNT | |
208 | + CHNLIB_Debug("Release(with free)[%p].", CHNLIB_DEBUG_ARGUMENTS, *structure); | |
209 | +#endif | |
210 | + free(*structure); | |
211 | + } else{ | |
212 | + strhead->destructor(structure); | |
213 | + } | |
214 | + } else{ | |
215 | +#ifdef DEBUG_MEMORY_REFERENCE_COUNT | |
216 | + CHNLIB_Debug("Release[%p].", CHNLIB_DEBUG_ARGUMENTS, *structure); | |
217 | +#endif | |
218 | + strhead->referenceCount--; | |
219 | + *structure = NULL; | |
220 | + } | |
221 | + } | |
222 | + | |
223 | + return; | |
224 | +} | |
225 | + | |
226 | +void *CHNLIB_AutoRelease(void *structure) | |
227 | +{ | |
228 | + //structureのreferenceCountを、destructせずに0にする。 | |
229 | + //オブジェクト確保後に自分の所有権を放棄して他の関数へ渡すときに利用する。 | |
230 | + | |
231 | + CHNLIB_StructureHeader *strhead; | |
232 | + | |
233 | + if(structure != NULL){ | |
234 | + strhead = (CHNLIB_StructureHeader *)structure; | |
235 | + if(strhead->signature == CHNLIB_STRUCTURE_SIGNATURE){ | |
236 | +#ifdef DEBUG_MEMORY_REFERENCE_COUNT | |
237 | + CHNLIB_Debug("Set AutoRelease [%p].", CHNLIB_DEBUG_ARGUMENTS, structure); | |
238 | +#endif | |
239 | + strhead->referenceCount = 0; | |
240 | + } | |
241 | + } | |
242 | + | |
243 | + return structure; | |
244 | +} | |
245 | + | |
163 | 246 | // |
164 | 247 | //Internal functions |
165 | 248 | // |
@@ -27,6 +27,7 @@ | ||
27 | 27 | |
28 | 28 | #ifdef DEBUG |
29 | 29 | //#define DEBUG_MEMORY_ALLOCATION |
30 | +//#define DEBUG_MEMORY_REFERENCE_COUNT | |
30 | 31 | #endif |
31 | 32 | |
32 | 33 | // |
@@ -42,6 +43,8 @@ struct CHNLIB_STRUCTURE_HEADER { | ||
42 | 43 | //ライブラリ共通構造体ヘッダ |
43 | 44 | uint signature; |
44 | 45 | uint typeid; |
46 | + uint referenceCount; | |
47 | + void (*destructor)(void **structrue); | |
45 | 48 | }; |
46 | 49 | |
47 | 50 | // |
@@ -61,6 +64,10 @@ struct CHNLIB_STRUCTURE_HEADER { | ||
61 | 64 | |
62 | 65 | #define CHNLIB_UIPArray_INDEX_NOTFOUND -1 |
63 | 66 | |
67 | +#define retain(structure) CHNLIB_Retain((void **) &structure) | |
68 | +#define release(structure) CHNLIB_Release((void **) &structure) | |
69 | +#define autorelease(structure) CHNLIB_AutoRelease(structure) | |
70 | + | |
64 | 71 | // |
65 | 72 | //Declare library functions |
66 | 73 | // |
@@ -72,7 +79,9 @@ void CHNLIB_StructureHeader_Initialize(CHNLIB_StructureHeader *header, uint type | ||
72 | 79 | uint CHNLIB_StructureHeader_GetTypeID(const void *structure); |
73 | 80 | void *CHNLIB_System_AllocateMemory_Strict(int size, const char filename[], int line, const char funcname[]); |
74 | 81 | void CHNLIB_System_FreeMemory(void *p, const char filename[], int line, const char funcname[]); |
75 | - | |
82 | +void CHNLIB_Retain(void **structure); | |
83 | +void CHNLIB_Release(void **structure); | |
84 | +void *CHNLIB_AutoRelease(void *structure); | |
76 | 85 | //@chnlib00.c |
77 | 86 | typedef struct CHNLIB_UIPARRAY CHNLIB_UIPArray; |
78 | 87 | struct CHNLIB_UIP_ARRAY; |
@@ -101,8 +110,8 @@ void *CHNLIB_UIPArray_GetPointerByData32(const CHNLIB_UIPArray *array, uint data | ||
101 | 110 | int CHNLIB_UIPArray_GetIndexByData32(const CHNLIB_UIPArray *array, uint data32); |
102 | 111 | //----配列のコピー |
103 | 112 | CHNLIB_UIPArray *CHNLIB_UIPArray_CopyArray(const CHNLIB_UIPArray *source); |
104 | -//----配列のソート | |
105 | -CHNLIB_UIPArray *CHNLIB_UIPArray_SortInDescendingOrderByData32(const CHNLIB_UIPArray *array); | |
113 | +//----配列のソートしたものを新たに取得 | |
114 | +CHNLIB_UIPArray *CHNLIB_UIPArray_GetSortedInDescendingOrderByData32(const CHNLIB_UIPArray *array); | |
106 | 115 | |
107 | 116 | //@chnlib01.c |
108 | 117 | typedef struct CHNLIB_STRING CHNLIB_String; |
@@ -26,6 +26,7 @@ | ||
26 | 26 | //Declare internal functions |
27 | 27 | // |
28 | 28 | CHNLIB_UIPArray *CHNLIB_UIPArray_Internal_Allocate(void); |
29 | +void CHNLIB_UIPArray_Internal_Destruct(void **structure); | |
29 | 30 | |
30 | 31 | // |
31 | 32 | //Define types |
@@ -39,6 +40,7 @@ struct CHNLIB_UIPARRAY_INTERNAL_TAG { | ||
39 | 40 | |
40 | 41 | struct CHNLIB_UIPARRAY { |
41 | 42 | //UnsignedIntとPointerを格納するArray構造体 |
43 | + //headerはすべてのpackにあるが、ReferenceCountはその特性上、先頭のものだけが有効である。 | |
42 | 44 | CHNLIB_StructureHeader header; |
43 | 45 | |
44 | 46 | int using_tags; //Number of using tags in this pack. |
@@ -59,6 +61,7 @@ int CHNLIB_UIPArray_AppendLast(CHNLIB_UIPArray **array, uint data32, void *point | ||
59 | 61 | { |
60 | 62 | //戻り値:追加されたタグのIndex |
61 | 63 | //Arrayの末尾にデータを追加する。 |
64 | + //追加された要素のpointerの参照先はArrayが所有する(Retain) | |
62 | 65 | int index; |
63 | 66 | |
64 | 67 | index = 0; |
@@ -73,6 +76,8 @@ int CHNLIB_UIPArray_AppendLast(CHNLIB_UIPArray **array, uint data32, void *point | ||
73 | 76 | (*array)->tag[(*array)->using_tags].pointer = pointer; |
74 | 77 | (*array)->using_tags++; |
75 | 78 | |
79 | + CHNLIB_Retain(&pointer); | |
80 | + | |
76 | 81 | return index + (*array)->using_tags - 1; |
77 | 82 | } |
78 | 83 |
@@ -98,7 +103,7 @@ int CHNLIB_UIPArray_RemoveByIndex(CHNLIB_UIPArray **array, int index) | ||
98 | 103 | { |
99 | 104 | //戻り値:削除が成功したか(0:成功,-1:指定された添字の要素は存在しない) |
100 | 105 | //indexが指し示す要素を削除し、後続の要素は前へつめる。 |
101 | - //削除された要素に格納されていたデータに関しては関知しない。 | |
106 | + //削除された要素のpointerの参照先の所有を放棄する(Release)。 | |
102 | 107 | int i; |
103 | 108 | |
104 | 109 | for(; (index / CHNLIB_UIPArray_INTERNAL_PACKDATAS) > 0; index -= CHNLIB_UIPArray_INTERNAL_PACKDATAS){ |
@@ -108,11 +113,17 @@ int CHNLIB_UIPArray_RemoveByIndex(CHNLIB_UIPArray **array, int index) | ||
108 | 113 | array = &(*array)->next; |
109 | 114 | } |
110 | 115 | if(*array == NULL){ |
116 | + //大雑把に見て、配列の範囲外 | |
111 | 117 | return -1; |
112 | 118 | } |
113 | 119 | if(index >= (*array)->using_tags){ |
120 | + //詳細に見て、一つのパックの中で、配列の範囲外 | |
114 | 121 | return -1; |
115 | 122 | } |
123 | + | |
124 | + //参照先の所有を放棄 | |
125 | + CHNLIB_Release(&(*array)->tag[index].pointer); | |
126 | + | |
116 | 127 | for(i = index; i < (*array)->using_tags - 1; i++){ |
117 | 128 | (*array)->tag[i] = (*array)->tag[i + 1]; |
118 | 129 | } |
@@ -120,8 +131,8 @@ int CHNLIB_UIPArray_RemoveByIndex(CHNLIB_UIPArray **array, int index) | ||
120 | 131 | if((*array)->next != NULL){ |
121 | 132 | if((*array)->using_tags != CHNLIB_UIPArray_INTERNAL_PACKDATAS || (*array)->next->using_tags == 0){ |
122 | 133 | //タグ数とリンクの関係があわない。以下の状態になっている。 |
123 | - //次のパックがあるのに、間のパックが使い切られていない。 | |
124 | - //次のパックがあるのに、次のパックに一つもデータがない。 | |
134 | + //-次のパックがあるのに、間のパックが使い切られていない。 | |
135 | + //-次のパックがあるのに、次のパックに一つもデータがない。 | |
125 | 136 | CHNLIB_ReportError("Internal data error.", CHNLIB_DEBUG_ARGUMENTS); |
126 | 137 | } |
127 | 138 | (*array)->tag[CHNLIB_UIPArray_INTERNAL_PACKDATAS - 1] = (*array)->next->tag[0]; |
@@ -311,7 +322,7 @@ CHNLIB_UIPArray *CHNLIB_UIPArray_CopyArray(const CHNLIB_UIPArray *source) | ||
311 | 322 | return destination; |
312 | 323 | } |
313 | 324 | |
314 | -CHNLIB_UIPArray *CHNLIB_UIPArray_SortInDescendingOrderByData32(const CHNLIB_UIPArray *array) | |
325 | +CHNLIB_UIPArray *CHNLIB_UIPArray_GetSortedInDescendingOrderByData32(const CHNLIB_UIPArray *array) | |
315 | 326 | { |
316 | 327 | //タグをData32の値で降順(大きい方から小さい方)になるように整列した新たなArrayを返す。 |
317 | 328 | CHNLIB_UIPArray *sorted, *temp; |
@@ -349,6 +360,8 @@ CHNLIB_UIPArray *CHNLIB_UIPArray_SortInDescendingOrderByData32(const CHNLIB_UIPA | ||
349 | 360 | } |
350 | 361 | } |
351 | 362 | |
363 | + release(temp); | |
364 | + | |
352 | 365 | return sorted; |
353 | 366 | } |
354 | 367 |
@@ -364,8 +377,43 @@ CHNLIB_UIPArray *CHNLIB_UIPArray_Internal_Allocate(void) | ||
364 | 377 | tag = (CHNLIB_UIPArray *)CHNLIB_System_AllocateMemory_Strict(sizeof(CHNLIB_UIPArray), CHNLIB_DEBUG_ARGUMENTS); |
365 | 378 | |
366 | 379 | CHNLIB_StructureHeader_Initialize(&tag->header, CHNLIB_STRUCT_ID_UIPArray); |
380 | + tag->header.destructor = &CHNLIB_UIPArray_Internal_Destruct; | |
367 | 381 | |
368 | 382 | return tag; |
369 | 383 | |
370 | 384 | } |
371 | 385 | |
386 | +void CHNLIB_UIPArray_Internal_Destruct(void **structure) | |
387 | +{ | |
388 | + //デストラクタ(実際にRelease->freeされる時に呼ばれる) | |
389 | + //方針:すべてのオブジェクトをReleaseした後、すべてのパックをFreeする。 | |
390 | + int i; | |
391 | + CHNLIB_UIPArray *array; | |
392 | + | |
393 | + if(structure == NULL){ | |
394 | + return; | |
395 | + } | |
396 | + if(CHNLIB_StructureHeader_GetTypeID(*structure) != CHNLIB_STRUCT_ID_UIPArray){ | |
397 | + return; | |
398 | + } | |
399 | + | |
400 | +#ifdef DEBUG_MEMORY_REFERENCE_COUNT | |
401 | + CHNLIB_Debug("Release(with free)[%p].", CHNLIB_DEBUG_ARGUMENTS, *structure); | |
402 | +#endif | |
403 | + | |
404 | + array = *structure; | |
405 | + | |
406 | + for(; array != NULL; array = array->next){ | |
407 | + for(i = 0; i < array->using_tags; i++){ | |
408 | + if(array->tag[i].pointer != NULL){ | |
409 | + CHNLIB_Release(&array->tag[i].pointer); | |
410 | + } | |
411 | + } | |
412 | + } | |
413 | + | |
414 | + CHNLIB_UIPArray_FreeOnlyArray((CHNLIB_UIPArray **)structure); | |
415 | + | |
416 | + return; | |
417 | +} | |
418 | + | |
419 | + |
@@ -31,6 +31,7 @@ char *CHNLIB_String_Intenal_NullCString = ""; | ||
31 | 31 | // |
32 | 32 | |
33 | 33 | CHNLIB_String *CHNLIB_String_Internal_Allocate(void); |
34 | +void CHNLIB_String_Internal_Destruct(void **structure); | |
34 | 35 | |
35 | 36 | // |
36 | 37 | //Define types |
@@ -53,6 +54,7 @@ CHNLIB_String *CHNLIB_String_Initialize(const char str[]) | ||
53 | 54 | CHNLIB_String *strtag; |
54 | 55 | |
55 | 56 | strtag = CHNLIB_String_Internal_Allocate(); |
57 | + strtag->header.destructor = &CHNLIB_String_Internal_Destruct; | |
56 | 58 | |
57 | 59 | if(str != NULL){ |
58 | 60 | CHNLIB_String_SetStringFromCString(strtag, str); |
@@ -357,4 +359,22 @@ CHNLIB_String *CHNLIB_String_Internal_Allocate(void) | ||
357 | 359 | CHNLIB_StructureHeader_Initialize(&tag->header, CHNLIB_STRUCT_ID_String); |
358 | 360 | |
359 | 361 | return tag; |
360 | -} | |
\ No newline at end of file | ||
362 | +} | |
363 | + | |
364 | +void CHNLIB_String_Internal_Destruct(void **structure) | |
365 | +{ | |
366 | + //デストラクタ(実際にRelease->freeされる時に呼ばれる) | |
367 | + if(structure == NULL){ | |
368 | + return; | |
369 | + } | |
370 | + | |
371 | +#ifdef DEBUG_MEMORY_REFERENCE_COUNT | |
372 | + CHNLIB_Debug("Release(with free)[%p].", CHNLIB_DEBUG_ARGUMENTS, *structure); | |
373 | +#endif | |
374 | + | |
375 | + CHNLIB_String_Free(*structure); | |
376 | + | |
377 | + *structure = NULL; | |
378 | + | |
379 | + return; | |
380 | +} |
@@ -62,7 +62,9 @@ int CHNLIB_UIPArray_GetSeparatedStringByUIPArray(CHNLIB_UIPArray **separated, co | ||
62 | 62 | { |
63 | 63 | //listにある文字列でsを分割し、その結果をseparatedに追加する。 |
64 | 64 | //listに存在する文字列は新しくメモリを確保せず、リスト中のStringタグへのポインタをseparatedに記録する。 |
65 | - //従ってseparatedを解放する際は、listのdata32をすべてTrueにした上で、CHNLIB_UIPArray_FreeSelectedAllを利用するべきである。 | |
65 | + ////従ってseparatedを解放する際は、listのdata32をすべてTrueにした上で、CHNLIB_UIPArray_FreeSelectedAllを利用するべきである。 | |
66 | + //referenceCountは、list中の文字列は2以上になり、listにない文字列は1となる。 | |
67 | + //従って、separatedをreleaseすれば、安全に解放できる。 | |
66 | 68 | //listにない文字列はdata32==False(0) |
67 | 69 | //listにある文字列はdata32==tag->data32 |
68 | 70 | int index, end, end_end, location; |
@@ -79,14 +81,14 @@ int CHNLIB_UIPArray_GetSeparatedStringByUIPArray(CHNLIB_UIPArray **separated, co | ||
79 | 81 | //もうリストの文字列はない |
80 | 82 | if(end != end_end){ |
81 | 83 | //でもまだ文字列は残っている |
82 | - CHNLIB_UIPArray_AppendLast(separated, False, CHNLIB_String_ExtractByLength(s, end, CHNLIB_MAX_STRING_LENGTH)); | |
84 | + CHNLIB_UIPArray_AppendLast(separated, False, autorelease(CHNLIB_String_ExtractByLength(s, end, CHNLIB_MAX_STRING_LENGTH))); | |
83 | 85 | } |
84 | 86 | break; |
85 | 87 | } |
86 | 88 | //リストの文字列が見つかった |
87 | 89 | if(location != 0){ |
88 | 90 | //リストの文字列の前に、リストにない文字列がある |
89 | - CHNLIB_UIPArray_AppendLast(separated, False, CHNLIB_String_ExtractByLength(s, end, location)); | |
91 | + CHNLIB_UIPArray_AppendLast(separated, False, autorelease(CHNLIB_String_ExtractByLength(s, end, location))); | |
90 | 92 | end += location; |
91 | 93 | } |
92 | 94 | CHNLIB_UIPArray_AppendLast(separated, CHNLIB_UIPArray_GetData32ByIndex(list, index), CHNLIB_UIPArray_GetPointerByIndex(list, index)); |
@@ -116,7 +118,7 @@ int CHNLIB_UIPArray_GetSeparatedUTF8Character(CHNLIB_UIPArray **separated, const | ||
116 | 118 | //終端文字 |
117 | 119 | break; |
118 | 120 | } |
119 | - CHNLIB_UIPArray_AppendLast(separated, u, CHNLIB_String_ExtractByLength(s, (int)(p - p_base), (int)(q - p))); | |
121 | + CHNLIB_UIPArray_AppendLast(separated, u, autorelease(CHNLIB_String_ExtractByLength(s, (int)(p - p_base), (int)(q - p)))); | |
120 | 122 | p = q; |
121 | 123 | } |
122 | 124 |
@@ -118,6 +118,7 @@ uint CHNLIB_UTF8_GetNextUnicodeOfCharacter(const char s[], const char **next) | ||
118 | 118 | } |
119 | 119 | |
120 | 120 | unicode = 0; |
121 | + mbsize = 0; | |
121 | 122 | for(i = 0; s[i] != '\0'; i++){ |
122 | 123 | n = CHNLIB_UTF8_GetCharacterType(s[i]); |
123 | 124 | switch(n){ |
@@ -11,28 +11,26 @@ | ||
11 | 11 | |
12 | 12 | int main(int argc, const char * argv[]) |
13 | 13 | { |
14 | - CHNLIB_String *s, *t; | |
14 | + //CHNLIB_String *s, *t; | |
15 | 15 | CHNLIB_UIPArray *separated; |
16 | + char str[1024]; | |
17 | + int i; | |
16 | 18 | |
17 | 19 | separated = CHNLIB_UIPArray_Initialize(); |
18 | - s = CHNLIB_String_Initialize("あいうえおかきくけこ"); | |
19 | - t = CHNLIB_String_Initialize("た"); | |
20 | 20 | |
21 | - CHNLIB_UIPArray_GetSeparatedUTF8Character(&separated, s); | |
21 | + for(i = 0; i < 32; i++){ | |
22 | + snprintf(str, sizeof(str), "Number %d.", i); | |
23 | + CHNLIB_UIPArray_AppendLast(&separated, i, autorelease(CHNLIB_String_Initialize(str))); | |
24 | + } | |
22 | 25 | |
23 | - printf("%d bytes, %d characters\n", CHNLIB_String_GetLength(s), CHNLIB_UTF8_GetStringLengthByCharacter(CHNLIB_String_GetReferencePointerOfCString(s))); | |
24 | - printf("%d bytes, %d characters\n", CHNLIB_String_GetLength(t), CHNLIB_UTF8_GetStringLengthByCharacter(CHNLIB_String_GetReferencePointerOfCString(t))); | |
26 | + CHNLIB_Debug_PrintStructureData(separated, 0); | |
27 | + | |
28 | + //CHNLIB_Release((void **)&separated); | |
29 | + release(separated); | |
25 | 30 | |
26 | - printf("match %d character(s).\n", CHNLIB_UTF8_CompareString_LeftHand(CHNLIB_String_GetReferencePointerOfCString(s), CHNLIB_String_GetReferencePointerOfCString(t))); | |
27 | - printf("match %d character(s).\n", CHNLIB_UTF8_CompareString_LeftHand(CHNLIB_String_GetReferencePointerOfCString(t), CHNLIB_String_GetReferencePointerOfCString(s))); | |
28 | - printf("match %d character(s).\n", CHNLIB_UTF8_CompareString_LeftHand(CHNLIB_String_GetReferencePointerOfCString(s), CHNLIB_String_GetReferencePointerOfCString(s))); | |
29 | - printf("match %d character(s).\n", CHNLIB_UTF8_CompareString_LeftHand(CHNLIB_String_GetReferencePointerOfCString(t), CHNLIB_String_GetReferencePointerOfCString(t))); | |
30 | - | |
31 | - printf("%d\n", CHNLIB_UTF8_GetCountOfContain(CHNLIB_String_GetReferencePointerOfCString(s), CHNLIB_String_GetReferencePointerOfCString(t))); | |
32 | 31 | |
33 | 32 | CHNLIB_Debug_PrintStructureData(separated, 0); |
34 | - printf("%d\n", CHNLIB_UIPArray_RemoveByIndex(&separated, 0)); | |
35 | - CHNLIB_Debug_PrintStructureData(separated, 0); | |
33 | + | |
36 | 34 | return 0; |
37 | 35 | } |
38 | 36 |