LINUX.ORG.RU

[C][dump question]длина неиниализированной строки

 


0

0

решил поучить C, есть такая программа

#include <stdio.h>
#include <string.h>
int main(){
char s[5];
printf(«len of %s %d\n»,s,strlen(s));
return 0;
}

функция strlen считает символы пока не наткнется на '\0', так как массив символов я не инициализирую, то там мусор, и функция выйдет за его границы, вопрос, почему при каждом запуске программы, в качестве строки s выводится мусор, в качестве длины всегда 34(как выяснилось зависит от объявленной длины массива), а если объявить масив с >40 символов, не инициализируя строку длина = 0, и строка пуста, если меньше 40 символов, то в строке мусор. Ктонить может объяснить это?



Последнее исправление: swelf (всего исправлений: 2)

любую память/переменную надо инициализировать перед использованием.
(С) К.О.

</thread>

k0l0b0k ★★
()

ну это понятно, вопрос не в том почему там мусор, а в том почему strlen всегда возвращает фиксированное значение, несмотря на различное содержимое строки? всегда в одном месте '\0' чтоли? и почему при объявлении массива больше 40 символов, длина равно 0.

swelf
() автор топика
Ответ на: комментарий от swelf

хм. не знаю. возми адресс чего-нибудь и посмотри

и еще раз - прочитай про стек и пойешь, почему он не является в полной мере мусором

namezys ★★★★
()

это зависит от того, что было в стеке до вызова main.

а поскольку до этого там как правило одно и то же (оболочка к main одна и та же), результат зависит только от того, насколько указатель стека уменьшен в начале работы main. почему он иногда одинаковый - размер локальных переменных довольно часто выравнивается.

sh-3.2$ cat 3.c
#include <stdio.h>
#include <string.h>
int main(){
	char s[19];
	printf("len of %s %d\n",s,strlen(s));
	return 0;
}
sh-3.2$ gcc -S -o - 3.c
	.file	"3.c"
	.section	.rodata
.LC0:
	.string	"len of %s %d\n"
	.text
.globl main
	.type	main, @function
main:
.LFB2:
	pushq	%rbp
.LCFI0:
	movq	%rsp, %rbp
.LCFI1:
	subq	$32, %rsp
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;      Было 19, стало 32 %)
;______________________________
.LCFI2:
	leaq	-32(%rbp), %rdi
	call	strlen
	movq	%rax, %rdx
	leaq	-32(%rbp), %rsi
	movl	$.LC0, %edi
	movl	$0, %eax
	call	printf
	movl	$0, %eax
	leave
	ret
.LFE2:
	.size	main, .-main
	.section	.eh_frame,"a",@progbits
.Lframe1:
	.long	.LECIE1-.LSCIE1
.LSCIE1:
	.long	0x0
	.byte	0x1
	.string	"zR"
	.uleb128 0x1
	.sleb128 -8
	.byte	0x10
	.uleb128 0x1
	.byte	0x3
	.byte	0xc
	.uleb128 0x7
	.uleb128 0x8
	.byte	0x90
	.uleb128 0x1
	.align 8
.LECIE1:
.LSFDE1:
	.long	.LEFDE1-.LASFDE1
.LASFDE1:
	.long	.LASFDE1-.Lframe1
	.long	.LFB2
	.long	.LFE2-.LFB2
	.uleb128 0x0
	.byte	0x4
	.long	.LCFI0-.LFB2
	.byte	0xe
	.uleb128 0x10
	.byte	0x86
	.uleb128 0x2
	.byte	0x4
	.long	.LCFI1-.LCFI0
	.byte	0xd
	.uleb128 0x6
	.align 8
.LEFDE1:
	.ident	"GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)"
	.section	.note.GNU-stack,"",@progbits
sh-3.2$ 

xydo ★★
()

Запусти gdb и полазь по стеку, если так интересно. А вообще некорректный код, он и в африке некорректный код, нет там ничего особо интересного.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

по поводу «запусти gdb», «полазь по стеку», по вопросу разве не понятно, что это темный лес для меня

swelf
() автор топика
Ответ на: Только в языка типа Си от wfrr

плолхо то, что, прочитав 60 страниц кернигана и ричи, я решил задать вопрос?

swelf
() автор топика
Ответ на: комментарий от swelf

Если это тёмный лес для тебя, то ответ: поведение в данном случае неопределено, и программа может делать что угодно, предсказывать её поведение бессмысленно, достаточно знать, что эта программа некорректна.

Legioner ★★★★★
()
Ответ на: комментарий от swelf

Это поведение также зависит от компилятора.

urxvt ★★★★★
()

> dump question

Если не знаешь язык, то не пиши на нём, особенно когда
можно почти то же самое написать на другом.

Sphinx ★★☆☆
()
Ответ на: комментарий от Sphinx

> dump question

dump



Я только сейчас понял, что же на самом деле имел в виду аффтор.

LamerOk ★★★★★
()
Ответ на: комментарий от gamecoder

лучше memset, ибо man bzero:

CONFORMING TO
4.3BSD. This function is deprecated (marked as LEGACY in POSIX.1-2001): use memset(3) in new programs. POSIX.1-2008 removes the specification of bzero().

sirius
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.