2014-03-18 4 views
0

В функции writeDmpFile Я звоню writeFile.Передача аргументов функции (int to size_t)

См. Код и комментарии.

Моя проблема - размер. В writeDmpFile я вижу это 380316. Я пытаюсь передать его в writeFile.

Но в то время как наступая сюда, я получаю очень большое количество (3832907636190596508).

Что я делаю неправильно. Я бы ожидал, что 380316 будет пройден.

int writeFile(char *name, unsigned char *buff, size_t *size,const char *dir) 
{ 
    FILE * pFile; 
    chdir (dir); 
    pFile = fopen (name, "wb"); 
    //(gdb) print *size 
    //$5 = 3832907636190596508 
    fwrite (buff , sizeof(unsigned char), *size, pFile); 
    fclose (pFile); 

    return 1; 
} 
int writeDmpFile(GTree *tree, char *filename) 
{ 
    char dmpfilename[32]; 

    dmpfilename[0] ='\0'; 
    dmpParams_t params; 
    params.buff[0] ='\0'; 
    int size =0; 
    params.size=&size ; 
    g_tree_foreach(tree, (GTraverseFunc)writeDmpFileLine, &params); 
    sprintf (dmpfilename, "InstrumentList_FULL.csv_%.*s", 15, filename); 
    //here (gdb) print size 
    //$1 = 380316 
    writeFile(dmpfilename, (unsigned char *)params.buff, (size_t *)&size , dmpdir);//(size_t *)params.size, dmpdir); 
} 
+0

Вы на самом деле не бросить. Происходит неявное преобразование. – ciphermagi

+1

@ciphermagi не существует неявного преобразования между типами указателей (кроме как с 'void *' и типами указателей объектов) – ouah

+0

@ciphermagi: Это так? – alk

ответ

2

Здесь есть две основные проблемы.

  1. Вы объявили size быть int, но на самом деле это должно быть size_t. Измените его тип на size_t.
  2. Вы не должны передавать адрес size на номер writeFile. Вы должны передавать его как параметр const. Вам не нужно его модифицировать и не делать. Поэтому сделайте это понятным в сигнатуре функции.

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

Итак, не подавляйте ошибки компилятора типа mismatch с отливками. Попробуйте понять, почему типы не совпадают и, таким образом, разрешают проблему.

1

Несмотря на вопрос, почему функция writeFile() настаивает на takeing в size через его адрес, есть два Каковы возможности для решения этой проблемы:

  1. Объявите промежуточные size_t -typed переменным:

    { 
        size_t _s = size; 
        writeFile(dmpfilename, (unsigned char *) params.buff, &_s, dmpdir); 
    } 
    
  2. Или используйте (хороший) составной код:

    writeFile(dmpfilename, (unsigned char *) params.buff, &((size_t){size}), dmpdir); 
    
+0

Я попытался использовать size_t, но теперь получил ошибку шины. Я редактировал код в своем вопросе. – MaMu

+0

@MaMu: Вы действительно должны ** не ** редактировать свой вопрос, поскольку он является основой для всего обсуждения здесь. И его редактирование может отбросить фон до большого количества ответов и комментариев. Откат назад. Если вы хотите добавить что-то, добавьте его в качестве обновления, оставив исходное содержимое. – alk

+0

@MaMu: Спасибо! :-) – alk

4
(size_t *)&size 

Это плохо, как size_t и int различные типы с различными представлениями. size_t - это псевдоним для целых чисел без знака, часто unsigned long. Здесь вы должны объявить size переменной size_t.

+0

Еще один приятный пример, почему кастинг диких - это плохая (не сказать опасная) привычка. – alk

+0

Мне нужно указать причину, по которой размер основывается на sprintf, который является int. – MaMu

+1

@MaMu в этом случае преобразует 'int' в' size_t' (перед проверкой это положительное значение), но не бросайте указатели. – ouah

0
(size_t *)&size 

Это большая ошибка, с которой вы сталкиваетесь при переходе от 32-битной системы к 64-битной системе. В 32-битной системе этот код может работать корректно, так как int и size_t будут иметь 32 бит. но на 64-битной системе int будет 32 бит, но size_t может иметь размер 64 бит.

В основном size_t был предназначен для хранения арифметики указателя.Это тип, возвращаемый оператором sizeof.

Для вашего решения проблем лучше конвертировать int size =0; в size_t size = 0

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