2014-10-21 1 views
0

У меня есть серьезная проблема с написанием приложения в Linux. У меня есть этот кодLinux <-> Windows Сохранение адреса строки

#include <stdio.h> 

int main() 
{ 
    char ar[10][10]; 
    strcpy(ar[1], "asd"); 
    strcpy(ar[2], "fgh"); 

    int test[2]; 
    test[1] = (int)ar[1]; 
    printf("%s %x | %s %x\n\n", ar[1], ar[1], test[1], test[1]); 

    return 0; 
} 

И это работает на Windows, хорошо, но когда я хочу, чтобы запустить это на Linux я получил Segmentation Fault или несанкционированный доступ к памяти.

+1

Ваша программа имеет * неопределенное поведение *, что в основном означает, что программа может делать что угодно, включая * работу как ожидалось *. Прочитайте [Неопределенные поведенческие и последовательные точки] (http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points) и [Что должен знать каждый программист C о неопределенном поведении] (http: // blog. llvm.org/2011/05/what-every-c-programmer-should-know.html) –

+0

@Blue: Я не вижу, какие точки последовательности должны быть связаны с этим обсуждением; здесь нет неопределенного поведения в результате многократной модификации переменных без промежуточных точек последовательности. –

ответ

3

Ваша программа вызывает неопределенное поведение. Предполагается, что указатель будет вписываться в int, что не требуется. Обычно указатели помещаются в Unix-боксы и не работают в Windows; но вы должны использовать подходящий целочисленный тип, например intptr_t от stdint.h, если вам нужно сделать такие преобразования. Обратите внимание, что строго говоря, целое число должно быть возвращено к типу указателя перед передачей printf.

Используя тип указателя на printf и большие результаты достаточно интегрального типа в правильном поведении: http://ideone.com/HLExMb

#include <stdio.h> 
#include <stdint.h> 

int main(void) 
{ 
    char ar[10][10]; 
    strcpy(ar[1], "asd"); 
    strcpy(ar[2], "fgh"); 

    intptr_t test[2]; 
    test[1] = (intptr_t)ar[1]; 
    printf("%s %x | %s %x\n\n", ar[1], ar[1], (char*)test[1], (char*)test[1]); 

    return 0; 
} 

Примечание, однако, что литейные указатели в целочисленных типов, как правило, одобряется и, скорее всего, приведет к программные ошибки. Не ходите туда, если вам абсолютно не нужно делать это по той или иной причине. Когда вы начинаете с C, маловероятно, что вам когда-нибудь понадобится это сделать.

+0

wow я полностью забыл об этом, спасибо человеку – Lukasas

+0

В качестве примечания стороны, вывод gcc дает предупреждение об этом, даже без опции -Wall. – spudone

Смежные вопросы