Pergunta

Eu sou novo para C e eu tenho esta pergunta. porque faz o seguinte acidente código:

int *a = 10;
*a = 100;
Foi útil?

Solução

Porque você está tentando escrever 100 para o local de memória 0x0000000A que provavelmente não é alocado para o seu programa. Ou seja,

int *a = 10;

não significa que o ponteiro 'a' irá apontar para uma localização na memória ter o valor de 10. Isso significa que ele está apontando para o endereço 10 (0x0000000A) na memória. Então, você quer escrever algo para esse endereço, mas você não tem os "direitos" a fazê-lo, uma vez que não é alocada

Você pode tentar o seguinte:

int *a = malloc(sizeof(int));
*a = 100;

Isso poderia funcionar, embora terrivelmente ineficiente. Se você só precisa de um único int, você deve apenas colocá-lo no pilha, não a pilha . Em um 32-bit architecure, um ponteiro é de 32 bits de comprimento, e um int é 32 bits de comprimento também, para que a sua estrutura de ponteiro-para-um-int ocupa ( pelo menos ) 8 bytes de espaço de memória desta maneira em vez de 4. E não temos sequer mencionado problemas de cache.

Outras dicas

Você precisa atribuir o ponteiro para um posição de memória , não o valor arbitrário (10).

int cell = 10;
int *a = &cell; // a points to address of cell
*a = 100;       // content of cell changed

Consulte minha resposta para outro pergunta, sobre ser cuidado com C .

Eu gostaria de propor uma ligeira mudança no uso de malloc (), para todas as respostas que sugerem que a utilizam para alocar memória para o int. Em vez de:

a = malloc(sizeof(int));

Eu sugeriria não repetir o tipo da variável, uma vez que é conhecido pelo compilador e repeti-lo manualmente tanto torna o código mais densa, e introduz um risco de erro. Se posteriormente você alterar a declaração de exemplo.

long *a;

Sem alterar a alocação, você iria acabar alocando a quantidade errada de memória (no caso geral, em máquinas int 32 bits e long são muitas vezes o mesmo tamanho). É, IMO, é melhor usar:

a = malloc(sizeof *a);

Isto significa simplesmente "o tamanho do tipo apontado para por um", neste caso int, que é, naturalmente, exatamente correto. Se você alterar o tipo na declaração acima, essa linha ainda está correto. Há ainda um risco, se você alterar o nome da variável no lado esquerdo da atribuição, mas pelo menos você não está mais informações repita desnecessariamente.

Além disso, note que nenhum parêntese são necessários com sizeof quando usá-lo em objetos reais (isto é, variáveis), apenas com nomes de tipos, que se parecem expressões elenco. sizeof não é uma função, é um operador.

Porque você nunca alocado qualquer memória para um. Você acabou alocados algum espaço de pilha para um ponteiro para a.

int *a = NULL;

a = malloc (sizeof (int));

if (a != NULL)
{
*a =10;
}

Will trabalho.

Como alternativa, você poderia dar um endereço de alguma variável existente, o que iria funcionar tão bem.

i.

int a* = NULL;
int b = 10;

a = &b;

Isto significa agora que fazer algo como

*a = 100;

também set b ser == 100

Confira esta: http://home.netcom.com/~tjensen/ptr/pointers.pdf

A seguinte linha,

int *a = 10;

define um ponteiro para um número inteiro a . Você, então, ponto o ponteiro um para a posição de memória 10.

A próxima linha,

*a = 100;

Coloca o valor 100 na posição de memória apontada por um.

O problema é:

  1. Você não sabe onde a aponta para. (Você não sabe o valor da posição de memória 10)
  2. Onde quer que a aponta para, você provavelmente não tem o direito a mudar esse valor. É provavelmente a memória algum outro programa / do processo. Seu ladrão!

Porque você declarar um ponteiro para int, initialize o ponteiro a 10 (um endereço) e, em seguida, tentar atribuir um valor para um int neste endereço. Como a memória no endereço 10 não pertence ao seu processo, você recebe um acidente. Isso deve funcionar:

int *a;
a = malloc(sizeof(int));
*a = 10;
printf("a=%i\n", *a);
free(a);

Será que este código ainda compila? 10 não é conversível para uma int *, a menos que você lançá-lo assim:

int *a = (int *) 10;
*a = 100;

Nesse caso, você está tentando escrever 100 para o endereço de memória em 10. Este não é geralmente um endereço de memória válido, portanto, seus programa falhar.

É provavelmente bater porque você está atribuindo o ponteiro para alguma parte da memória que você não tem acesso e, em seguida, você está atribuindo algum valor a esse local de memória (que você não está autorizado a fazer!).

Você também pode escrevê-lo como:

int* a = 10;
*a = 100;

Observe a diferentes espaçamentos na primeira linha. Não é um estilo popular, mas eu pessoalmente acho que é mais clara. Ele tem exatamente o mesmo significado para o compilador.

Em seguida, lê-lo em voz alta:

"Pointer-to-int 'a' becomes 10"
"Value-pointed-to-by 'a' becomes 100"

Substituindo o valor real:

"Value-pointed-to-by 10 becomes 100"

... em que você percebe que 10 é improvável que apontam para um pedaço de memória que você pode usar.

Você praticamente nunca iria atribuir a um ponteiro com um literal:

int* ptr = (int*)10;  // You've guessed at a memory address, and probably got it wrong
int* ptr = malloc(sizeof(int)); // OS gives you a memory address at runtime  

Eu acho que pode haver alguns muito baixo nível postos de trabalho onde você especificar diretamente endereços de memória absolutos. implementação do kernel, por exemplo?

Ok, tentando dar a explicação mais simples hoje, ao tentar dar-lhe imagem mais detalhada sobre tudo. Vamos adicionar alguns parênteses vamos?

(int*) a = 10;
(*a) = 100;

Você tenta escrever quatro bytes para o endereço do intervalo [10-13]. O layout de memória do seu programa começa normalmente mais elevados, assim que sua aplicação não acidentalmente nada de substituição de onde podia e ainda função (de .data, .bss, e pilha por exemplo). Por isso, acaba por deixar de funcionar em vez disso, porque o endereço de gama não foi alocado.

ponteiro aponta para uma localização de memória e tipagem estática C define um tipo para um ponteiro. Embora você pode substituir o ponteiro facilmente. Simplesmente:

(void*) v = NULL;

Aqui nós ir mais longe para as coisas. O que é um ponteiro nulo? É simplesmente ponteiro que aponta para o endereço 0.

Você também pode dar um tipo struct para o ponteiro:

struct Hello {
    int id;
    char* name;
};

...

struct Hello* hello_ptr = malloc(sizeof Hello);
hello_ptr->id = 5;
hello_ptr->name = "Cheery";

Ok, o que é malloc? Malloc Aloca memória e retorna um ponteiro para a memória alocada. Ele tem um seguinte assinatura de tipo:

void* malloc(size_t size);

Se você não tem um coletor de lixo conservador, é provável que a sua memória não vai acabar por ser libertado automaticamente. Portanto, se você deseja obter a parte de trás de memória em uso do que você apenas alocado, você deve fazer:

free(hello_ptr);

Cada malloc você tem um tamanho-tag nele, assim você não precisa declarar o tamanho do pedaço que você apontou para -routine livre.

Ok, mas uma coisa, o que faz uma cadeia de caracteres olhar como na memória? A única semelhante ao "animador", por exemplo. A resposta é simples. É uma matriz de bytes terminada em zero.

0.1.2.3.4.5. 6
C h e e r y \0
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top