我打算创建一个与scanf类似的函数,但我不需要定义char数组的长度,只需定义指针(并使用malloc())。
此时,我想让这个头文件只需要包含并在需要时使用它。
这是我的外部函数,在string.variavel.h
:
# include <stdio.h>
# include <stdlib.h>
void pegastr( char *str ){
char x , *guardaStr ;
unsigned int i , j ;
str = malloc( 1 );
str[0] = '\0';
for( j = 0 ; x != '\n' ; ++j ){
x = getc( stdin );
fflush( stdin );
guardaStr = malloc( j );
for( i = 0 ; i < j ; ++i ){
guardaStr[i] = str[i];
}
str = malloc( 1 + j );
for ( i = 0 ; i < j + 1 ; ++i ){
if( guardaStr[i] == '\0' ){
str[i] = x ;
}else{
str[i] = guardaStr[i] ;
}
}
str[i] = '\0';
}
}
这是我的函数调用并包含外部:
# include "string.variavel.h"
int main(void){
char *palavrao , *torrada;
pegastr( palavrao );
pegastr( torrada );
printf( "%s\n%s" , palavrao , torrada );
return 0;
}
所以,我的问题是,如果我将pegastr()
的所有代码复制到main()内部,当我尝试输出它工作的字符串时,但是,如果我不这样做并让代码保持现状,当我尝试输出main()中字符串的值时,我只在每个printf()获得(null)。
我认为我的问题是我在函数pegastr()
的参数中发送/接收的地址,但我看不到需要更改的内容。
感谢你的帮助!
答案 0 :(得分:1)
您粘贴的代码在内存处理方面存在很多问题。你有内存泄漏,你在那里做的不是很清楚。
我将根据我在阅读您的问题后所理解的问题解决您遇到的主要问题。这通常是关于指针及其工作原理。
如果要在函数中分配指针并返回它,可以A)传递指针指针或B)返回指针。
A)
// call: myallocator(&element, size)
void myallocator(char **element, size_t size)
{
*element = malloc(size);
// ...
}
B)
// call: element = myallocator(size)
char* myallocator(size_t size)
{
char *mem;
mem = malloc(size);
// ...
return mem;
}
答案 1 :(得分:0)
如果我将所有代码复制到main
,它仍会打印null
。通常,您的程序具有未定义的行为,并且无法正常工作(无论您将代码放在何处)
您的第一个问题是功能不会更改palavrao
和torrada
的值。该函数只是用指针的值调用,无论你在函数内部改变多少值,外部的变量仍然具有相同的值。
相反,你可以这样做:
void pegastr( char **str ){ // Note double pointer
....
*str = malloc(....
}
// Called like
pegastr( &palavrao );
或喜欢
char* pegastr(){ // Return the malloc'ed pointer
char * tmp = malloc(....
....
return tmp;
}
// Called like
palavrao = pegastr();
除此之外,您的代码还需要解决许多问题:
for( j = 0 ; x != '\n' ; ++j ){
^
x is uninitialized when the loop starts
和
guardaStr = malloc( j );
^
Do you want this when j is 0 ?
Or do you really want j + 1 here ?
此外,当您运行此代码第2,第3 ......时间时,您会发生内存泄漏。在使用新指针覆盖旧指针之前,需要释放内存。
内存泄漏也适用于:
str = malloc( 1 + j );
在这里:
if( guardaStr[i] == '\0' ){
^^^^^^^^^^^^
Access outside allocated memory (e.g. when j is 0)
我建议您阅读realloc
- 这是您的代码的更好选择。
使用realloc
代码可能类似于:
# include <stdio.h>
# include <stdlib.h>
void pegastr( char **str ){
char *tmp;
char x;
unsigned int j ;
tmp = malloc( 1 );
if (tmp == NULL)
{
// Out of memory
exit(1);
}
str[0] = '\0';
j = 1; // Notice: j starts from 1
while(1){
x = getc( stdin );
if (x == '\n')
{
// Don't copy the \n - just break the loop
break;
}
fflush( stdin );
// Insert the new char and a termination
tmp = realloc(tmp, j+1);
if (tmp == NULL)
{
// Out of memory
exit(1);
}
tmp[j-1] = x;
tmp[j] = '\0';
// Increment j
++j;
}
// Update the input pointers value
*str = tmp;
}
int main(void){
char *palavrao , *torrada;
pegastr( &palavrao );
pegastr( &torrada );
printf( "%s\n%s\n" , palavrao , torrada );
free(palavrao);
free(torrada);
return 0;
}