開發c/c++模組時,因為很多記憶體資源都需要自己釋放,為了統一乙個地方釋放資源通常用goto標籤在函式退出時釋放資源,好處是資源統一釋放,不會因為在提前return時分別釋放資源導致以後修改**遺漏釋放某些資源導致死鎖或者記憶體洩漏。
以下是goto模式
void goto_function()
snprintf(buf, 64, "hello goto function");
printf("%s\n", buf);
label_exit:
if (null != buf)
return;
}
這是比較簡單的goto**,所以看起來沒那麼彆扭。假如我們用在修改**如下:
void goto_function()
size_t len = 0; // 在goto 的label第一次使用之後,宣告臨時變數
snprintf(buf, 64, "hello goto function");
len = strlen(buf);
printf("%s\n", buf);
label_exit:
if (null != buf)
return;
}
編譯會出現如下錯誤
$ g++ main.cpp
main.cpp:9:3: error: cannot jump from this goto statement to its label
goto label_exit;
main.cpp:11:9: note: jump bypasses variable initialization
size_t len = 0; // 在goto 的label第一次使用之後,宣告臨時變數
1 error generated.
如果在goto第一次使用之後,那麼不能繼續建立臨時變數了。因為label不知道在label第一次使用之後的臨時變數。要修改需要把臨時變數的宣告放在goto label之前
void goto_function()
snprintf(buf, 64, "hello goto function");
len = strlen(buf);
printf("%s\n", buf);
label_exit:
if (null != buf)
return;
}
再編譯就相安無事。
變數在函式頭集體申明其實非常不利於**的可讀性,不利於檢視臨時變數的型別,增加冗餘**行,不能盡量讓區域性變數變數宣告和定義放在一處執行,為了避免這種情況,我們需要規避goto帶來的弊端,可以用 do while配合break
void none_goto_function()
snprintf(buf, 64, "hello none goto function");
size_t len = 0; // 在do while內宣告臨時變數
len = strlen(buf);
printf("%s\n", buf);
} while(0);
if (null != buf)
return;
}
這裡利用了do while的break特性降解goto帶來的無法鄰近宣告區域性變數的弊端。不過只是暫時規避而已,因為break也是有缺點的,當do while內的迴圈或者switch也用到了break,這時候也會降低break程式的可讀性。例如:
void none_goto_nest_break_function()
for (int i = 0; i < 5; i++)
}snprintf(buf, 64, "hello none goto function");
printf("%s\n", buf);
} while(0);
if (null != buf)
return;
}
對付這種情況可以盡量將for迴圈內的**用函式封裝,大部分迴圈內**都能夠抽象為乙個簡單的函式。
ps: 不過抽象為函式又會影響執行效能,總之也不是終極解決方案。
goto語句可釋放資源避免記憶體洩漏
程式異常判斷時,有問題,往往會使用return 雖然後面的程式執行過程被跳過了,但是後面的資源釋放的語句也被跳過了。在資源釋放的語句之前加個名稱 比如mylocation goto mylocation 語句直接跳過後面的語句,直接跳轉到mylocation位置,執行資源釋放的語句。執行效果類似於r...
goto對資源的釋放問題的解決
q 一塊 中有大於1的資源的分配時,很容易造成跳過資源的釋放 從而導致資源的洩露。a 利用goto語句的跳轉特點可以一定程度上解決這個問題 example file f1 open if null f1 goto error1 file f2 open if null f2 goto error2 ...
鍊錶節點被刪除時的資源釋放
演算法專題 鍊錶 鍊錶系列之 無序單鏈表去重 鍊錶系列之 滑動視窗問題 所有生成視窗的最大值的集合 問題 眾所周知,鍊錶結構相對於陣列結構的乙個優秀之處在於其刪除元素操作僅靠更改指標指向即可完成,而陣列則需要移動元素。但鍊錶中被刪除的元素所占用的資源是否需要被釋放?分析 這個問題的關鍵在於組成鍊錶的...