صب مجموعة الأحرف غير الموقعة على المدى الطويل [مغلق]

StackOverflow https://stackoverflow.com//questions/21048578

سؤال

لست متأكدًا مما إذا كان هذا صحيحًا، لقد قمت باختباره ويبدو أن بعض البايتات معطلة ...في الأساس، لدي ما يلي:

unsigned char szBuffer[1024] = {0};
long long nValue = 1334553536;
memcpy(szBuffer, (char*)&nValue, sizeof(long long));

//

long long nNewValue = reinterpret_cast<long long>(szBuffer);
printf(nNewValue); //prints out a smaller number than previously stated

هل يمانع أحد في الإشارة إلى أين أخطأت؟شكرًا لك.

هل كانت مفيدة؟

المحلول

أنت تقوم بالإعداد nNewValue إلى عنوان szBuffer, ، بدلاً من قراءة البيانات من هذا العنوان.يستخدم:

long long nNewValue = *reinterpret_cast<long long*>(szBuffer);

نصائح أخرى

تغيير هذا البيان

long long nNewValue = reinterpret_cast<long long>(szBuffer);

ل

long long nNewValue = *reinterpret_cast<long long *>(szBuffer);

إليك نسخة معدلة من برنامجك الذي يعمل على نظامي (موسع إلى برنامج كامل):

#include <iostream>
#include <cstring>
int main() {
    unsigned char szBuffer[1024] = {0};
    long long nValue = 1334553536;
    std::memcpy(szBuffer, &nValue, sizeof(long long));
    long long nNewValue = *(reinterpret_cast<long long*>(&szBuffer));
    std::cout << nValue << "\n" << nNewValue << "\n";
}

memcpyالمعلمتان الأوليتان من النوع void*, ، لذلك لا تحتاج إلى إلقائهم؛إذا قمت بإرسالها (هل تم إهمال هذا التحويل في C++؟)، فيجب عليك الإرسال إلى void*, ، لا char*.

التكليف به nNewValue يحول عنوان من المخزن المؤقت ل long long*, ، ثم قم بإلغاء الإشارة إلى القيمة المحولة.

لكن هذه فكرة سيئة.يعطيني g++ تحذيرًا بشأن عدم مرجعية المؤشر المحول:

warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

علاوة على ذلك، ليس هناك ما يضمن ذلك szBuffer, ، وهي عبارة عن مجموعة من unsigned char, ، تمت محاذاته بشكل صحيح بحيث يمكن التعامل مع وحدات البايت القليلة الأولى بأمان على أنها ملف long long هدف.يتحمل نظام x86 أو x86_64 الذي تستخدمه على الأرجح عمليات الوصول إلى الذاكرة غير المتوافقة، ولكن ليس كل الأنظمة تفعل ذلك.

غالبًا ما تكون قوالب المؤشر غير آمنة إلا إذا كنت تعرف ذلك بالضبط ماذا تفعل.

إذا كنت تريد إعادة تفسير جزء من مصفوفة أحرف ككائن من نوع آخر، فيمكنك استخدام الاتحاد إذا كنت تريد بالفعل تفسير الذاكرة نفسها كنوع مختلف من الكائنات، أو استخدام memcpy.(ومع ذلك، تأكد من أنك تحتاج حقًا إلى القيام بذلك؛فمن المحتمل أنك لا تفعل ذلك.في معظم الأحيان، إذا كنت ترغب في تخزين ملف long long الكائن، يجب عليك فقط يُعرِّف أ long long هدف.)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top