2016-09-07 2 views
-1

это код, я использую:Случайно создать гигантский файл с записью

#include <stdio.h> 
#include <stdlib.h> 
void main(){ 
    test = creat("TEST",0751); 
    close(test); 
    test = open("TEST",2); 
    write(test, "123456789101112131415",21); 
    lseek(test,-2,2); 
    read(test,swap_array,2); 
    write(test,swap_array,2); 
    lseek(test,-6, 1); 
    write(test,"xx",2); 
} 

Это создает 8gb файл, содержащий вместо вставки «ого» в между числами, как я намерен. Что не так с кодом, как у меня?

+1

Поскольку вы не показываете свои '# include', мы не можем знать, какие прототипы находятся в сфере видимости. Пожалуйста, предоставьте краткую ** полную ** программу, которая демонстрирует вашу ошибку.См. [Mcve] для получения дополнительной информации. –

+2

Используйте константы вместо магических чисел! Почему нам нужно перевести их во что-либо значимое? –

ответ

3

Вы не смогли включить соответствующие файлы заголовков. Вы должны включать, как минимум:

#include <sys/types.h> 
#include <unistd.h> 
#include <fcntl.h> 

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

Вот рабочая версия вашей программы:

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 


int main() { 
char swap_array[2]; 
int test = creat("TEST",0751); 
close(test); 
test = open("TEST",O_RDWR); 
write(test, "123456789101112131415",21); 
lseek(test,-2,SEEK_END); 
read(test,swap_array,2); 
write(test,swap_array,2); 
lseek(test,-6, SEEK_CUR); 
write(test,"xx",2); 
return 0; 
} 
+0

Я бы также заменил флаги для 'creat' ... –

+0

Заголовки решают проблему. И флаги, которые я скопировал, вставляли строго для примера. –

+0

@EugeneSh. Канонические флаги для 'creat()' - или третий аргумент 'open()' - крайне сложны: ['S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH'] (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html) для '0751'. Гораздо проще читать восьмеричную, чем стандартную. –

3

Вы, вероятно, не включая заголовки, так что, наверное, не прототип для lseek() в объеме, поэтому 2 в середине аргумента является int, но lseek() ожидает (long) off_t, и вы на 64-битной машине, где sizeof(int) != sizeof(long) так два 2 «s неверно интерпретируются системным вызовом (возможно, рассматривая их как смещение и по какой-либо причине, что осталось на стек интерпретируется reted как SEEK_SET или иначе переходит на большое смещение).

В принципе, вы, вероятно, передаете неточно набранную информацию в системный вызов, потому что вы не включили правильные заголовки. Классический (до POSIX вмешивался), средний 2 будет 2L, потому что l в lseek() постоял «долго» - до этого был seek(), который взял обычную int (в дни 16-битные int типов) - к убедитесь, что long принят как lseek() . В эти дни lseek() требует: off_t; использование прототипа имеет решающее значение для обеспечения правильной интерпретации того, что вы пишете, как off_t.

В этом описании есть много UB, но факт, что вы не используете SEEK_SET и т. Д., Создает предупреждающие флаги. Кроме того, почему файл является исполняемым? Это не похоже на исполняемый код, который вы пишете.

Этот вариант кода более осторожен (и не создает 8-гигабайтный файл в Mac OS X 10.11.6 с GCC 6.2.0).

#include <fcntl.h> 
#include <sys/stat.h> 
#include <unistd.h> 

#define MODE_0751 (S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH) 

int main(void) 
{ 
    // All error checking omitted 
    char swap_array[2]; 
    int test = creat("TEST", MODE_0751); 
    close(test); 
    test = open("TEST", O_RDWR); 
    write(test, "123456789101112131415", 21); 
    lseek(test, -2L, SEEK_END); 
    read(test, swap_array, 2); 
    write(test, swap_array, 2); 
    lseek(test, -6L, SEEK_CUR); 
    write(test, "xx", 2); 
    close(test); 
    return 0; 
} 

Я использую L «S из (очень) по старой привычке, но они необязательны. Различные 2 могут быть заменены на sizeof(swap_array)sizeof("xx")-1). Я довольно давно узнал C, что восьмеричные разрешения были единственным способом ведения бизнеса; S_IRWXU и родственные имена были годами в будущем. Я нахожу четырехзначное или 5-значное восьмеричное число более читаемым, чем строка из S_Iwxyz имен.

Убедитесь, что вы скомпилировали свой код с настройками, чтобы прототипы были необходимы, прежде чем вы сможете использовать функции. Например, я использую:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \ 
>  -Wstrict-prototypes -Wold-style-definition mx19.c -o mx19 
$ 
+0

', так что два двух обработаны ... »Я сомневаюсь: и AMD, и MS ABI будут использовать регистры для передачи первых 4 аргументов на x64. – Serge

+0

@Serge, может быть, это i386. – fuz

+0

Технически второй аргумент 'lseek()' is 'off_t', а не' int' или 'long'. – EOF

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