Birkaç platformda C++ ile snprintf uygulamasının çok garip bir davranışını (bence) fark etmedim. Aşağıdaki kodu (gözlenen davranışı neden olan asgari çalışma örneği) düşünün:Beklenmedik snprintf davranışı
#include <stdio.h>
char test1[512];
char test2[512];
char test3[1024];
char test4[1024];
int main()
{
snprintf(test1, sizeof(test1), "test1");
snprintf(test2, sizeof(test2), "test2");
snprintf(test3, sizeof(test3), "%s %s", test1, test2);
return 0;
}
= exp-sgcheck, aşağıdaki hata (3 snprintf deyimi için) bildirilmektedir --tool ile valgrind olsa çalışan:
==30302== Invalid read of size 1
==30302== at 0x568E4EB: vfprintf (in /lib64/libc-2.19.so)
==30302== by 0x56B7608: vsnprintf (in /lib64/libc-2.19.so)
==30302== by 0x5695209: snprintf (in /lib64/libc-2.19.so)
==30302== by 0x4006AD: main (1.cc:12)
==30302== Address 0x601460 expected vs actual:
==30302== Expected: global array "test1" of size 1,024 in object with soname "NONE"
==30302== Actual: global array "test2" of size 512 in object with soname "NONE"
==30302== Actual: is 0 after Expected
Test1'i ilk% s argümanı olarak geçirdikten sonra, test1 dizisinin sonuna kadar okunan bir okumaya yol açar.
Bu davranış
(evet ben ... statik verileri biliyorum) bir windows sürücüsü birkaç sayfa hataları neden oldu. Neyse ki kod taşınabilir ve linux valgrind'e taşındığında bu hata bildirildi.Ama benim gördüğüm kadarıyla
, snprintf (öyle ki, o işaretli) 6 byte olarak \ 0 ile test1 sonlandırmak gerekir. Peki neden 3. snprintf ifadesinin test1 dizisinin sonundan sonra okunmasına neden sebep oluyor? 3. snprintf ifadesinin 'un her iki platformdaki sorununu çözmesi. Kodu C kodu (C++ değil) olarak derlemek hiç hataya neden olmaz.GÜNCELLEME: hata yalnızca oluşur linux üzerinde (ve belki pencereler yanı), kod ayıklama bilgileri ile derlenmiş dahildir ve optimizasyonlar (gcc için -g O0) devre dışı bırakılırsa.
Bu durumda bir değişiklik yapması gerekmiyor, ancak kaynak dosya adı valgde çıktısında "1.cc" olarak çağrılıyor. C yazmak ve bir C++ derleyicisi ile derlemek için bir neden var mı? – Blrfl
Sadece kodunuzu "valgrind --tool = exp-sgcheck" ile test ettim ve hata bildirilmedi, hangi "valgrind" sürümünü kullanıyorsunuz ve glibc'nin hangi sürümünü kullanıyorsunuz, ayrıca Linux Distro'nuz nedir? –
Bize biraz daha anlatabilir misiniz? Örneğin. platformunuz, derleyici sürümünüz, kodu nasıl derlersiniz. – nos