首頁>Program>source

我知道在C ++ 03中,从技術上讲, std::basic_string 模板不需要具有连續的記憶體.但是,我很好奇實際上有這種自由的現代編譯器有多少種實現.例如,如果要使用 basic_string 要接收某些C API的結果(如下面的示例),分配向量只是立即將其轉換為字元串似乎很愚蠢。

示例:

DWORD valueLength = 0;
DWORD type;
LONG errorCheck = RegQueryValueExW(
        hWin32,
        value.c_str(),
        NULL,
        &type,
        NULL,
        &valueLength);
if (errorCheck != ERROR_SUCCESS)
    WindowsApiException::Throw(errorCheck);
else if (valueLength == 0)
    return std::wstring();
std::wstring buffer;
do
{
    buffer.resize(valueLength/sizeof(wchar_t));
    errorCheck = RegQueryValueExW(
            hWin32,
            value.c_str(),
            NULL,
            &type,
            &buffer[0],
            &valueLength);
} while (errorCheck == ERROR_MORE_DATA);
if (errorCheck != ERROR_SUCCESS)
    WindowsApiException::Throw(errorCheck);
return buffer;

我知道這樣的代碼可能会稍微降低可移植性,因為它暗示了 std::wstring 是连續的-但是我想知道這段代碼是多麼难以移植.換句话說,編譯器實際上如何利用不连續記憶體允许的自由?


編輯:我更新了此問题以提及C ++ 03.讀者應註意,在针對C ++ 11時,该標準現在要求 basic_string 是连續的,因此在针對该標準時,上面的問题不是問题。

最新回復
  • 5月前
    1 #

    我认為假設std :: string连續分配其儲存是非常安全的。

    目前, std::string的所有已知實現 连續分配空間.

    此外,C ++ 0x(N3000)的当前草案[編輯:警告,直接鏈接到大PDF]要求连續分配空間(第21.4.1 / 5节):

    The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0 <= n < s.size().

    因此,当前或將来實施 std::string的機会 使用非连續儲存基本上是零。

  • 5月前
    2 #

    前一陣子,關於能够為 std::string寫入儲存存在一个問题 好像它是一个字元陣列,並且取決於一个 std::string的內容 是连續的:

      Is it legal to write to std::string?

    我的迴答表明,根据一些公认的訊息来源(Herb Sutter和Matt Austern),当前的C ++標準確實需要 std::string 在某些條件下连續儲存其資料(一旦您致電 str[0] 假設 str 是个 std::string ),這一事實几乎在任何實施方面都起着作用。

    基本上,如果您結合 string::data()的承诺 和 string::operator[]() 您得出的結論是, 需要返迴一个连續的緩衝區.因此,奥斯汀建議委員会將其明確化,顯然這就是0x標準中發生的事情(或者現在將其稱為1x標準吗?)。

    因此嚴格来說,實現不必實現 &str[0] 使用连續儲存,但是它几乎必须按需執行.您的示例代碼通過傳入 std::string来實現此目的

    鏈接:

    &buffer[0] p

    結果不確定,我不会這樣做.在現代c ++堆中,讀入向量然後轉換為字元串的成本是微不足道的. VS您的代碼將在windows 9中死亡的风险

    還不需要在&buffer [0]上进行const_cast吗?

  • 5月前
    3 #

      Herb Sutter's comment

      Matt Austern's C++ Standard Library Defect Report

      previous SO answer

    您想打電话给 Edit:not &buffer[0] ,因為 buffer.data() 返迴非 [] reference和会通知物件其內容可能会意外更改。


    const会更簡潔 ,但是与結構之間共享的記憶體相比,您不必担心连續記憶體. buffer.data() 實現可以而且確實希望在物件被修改時被告知. string 专門要求程式不要修改返迴的內部緩衝區。

    除了长度設置為10或其他任何值外,某些實現非常有可能為所有未初始化的字元串建立一个緩衝區。

    使用 string::data 甚至是 vector的陣列 / new[] .如果您確實無法複製緩衝區,請在更改之前合法地將字元串初始化為唯一的字元串。

  • 5月前
    4 #

    当然,在此處分配向量很愚蠢.在這裏使用std :: wstring也是不明智的.最好使用char陣列呼叫winapi.返迴值時構造一个wstring。

    delete[]

  • f#:如何約束一个型別引數
  • python:用Python方式計算Pandas DataFrame列中列表的长度