我正在尝试学习C,我在翻转字符串时收到此错误。我不熟悉内存分配的东西,请你指出我做错了什么。
#include<stdio.h>
#include<string.h>
char* strrev(char *str);
int main()
{
char str[1000];
char *str1;
printf("Please enter a String\n");
gets(str);
str1=strrev(str);
puts(str1);
}
char* strrev(char *str)
{
char *str1;
int i,length,c;
length=strlen(str);
for (i=length-1;i<=0;i--)
{
*(str1+c) = *(str+i);
c++;
}
*(str1+c) ='\0';
return str1;
}
答案 0 :(得分:2)
在strrev()
函数内,str1
未分配内存。因此,*(str1+c) = *(str+i);
是UB。
然后,c
是一个自动局部变量,在使用前未初始化。还有UB。
接下来,as Giorgi mentioned,更正你的for循环。
也就是说,不要使用gets()
,它会遇到缓冲区溢出问题。请改用fgets()
。
答案 1 :(得分:2)
for (i=length-1;i<=0;i--)
由于i<=0
,这将永远不会(除非字符串长度为0或1个字符),应该i>=0
。
通常,您还需要使指针指向某个有效的内存,以便能够取消引用它。在您的情况下,您应该使用malloc
来分配足够数量的字节,并将其结果分配给str1
。然后你可以像往常一样写信给它。
答案 2 :(得分:0)
在您的函数中,您没有初始化SELECT u.ID, u.user_login, u.user_registered, u.display_name
FROM
(
SELECT user_id, MAX(create_date) AS max_create_date
FROM purchase_key
WHERE product_id IN (1, 2)
AND create_date BETWEEN '2014-09-01' AND '2015-09-20'
GROUP BY user_id
) p
INNER JOIN users u ON p.user_id = u.id
ORDER BY p.max_create_date ASC
c
并在int i,length,c;
循环
for
还有其他问题..
1)函数内的*(str1+c) = *(str+i);
没有分配内存。
2)此循环永远不会被执行,因为str1
中的条件永远不会为真(除非字符串为0或1个字符长)。
3)不要使用for (i=length-1;i<=0;i--)
,不推荐使用它。而是使用gets()
答案 3 :(得分:0)
str1
strrev()
i<=0
为false,并且for
循环内的块不会被执行。*(str1+c) ='\0';
会导致崩溃,因为str1
的值是不确定的,str1
指出某个有效位置的可能性很小。 UPD:c
中的strrev()
也未初始化,会造成一些麻烦。
答案 4 :(得分:0)
您要做的不是反转字符串。程序中的字符串都没有反转。您试图以相反的顺序在另一个字符串中复制一个字符串。
因此,您要以相反的顺序复制原始字符串的sring应该有足够的空间来存储复制的字符。
但是在你的功能中
char* strrev(char *str)
{
char *str1
//...
指针str1
未初始化,并未指向适当大小的内存范围。
所以你的程序有不确定的行为。
另请注意,函数gets
不安全,不再受C标准支持。请改用函数fgets
。
如果您的编译器支持可变长度数组(VLA),那么程序可以采用以下方式
#include <stdio.h>
#include <string.h>
char * reverse_copy( char *s2, const char *s1 )
{
size_t n = strlen( s1 );
size_t i = 0;
for ( ; i < n; i++ ) s2[i] = s1[n-i-1];
s2[i] = '\0';
return s2;
}
int main( void )
{
char s1[1000];
printf( "Please enter a String: " );
fgets( s1, sizeof( s1 ), stdin );
size_t n = strlen( s1 );
if ( n != 0 && s1[n-1] == '\n' ) s1[n-1] = '\0';
char s2[n + 1];
puts( s1 );
puts( reverse_copy( s2, s1 ) );
return 0;
}
如果要输入例如
Hello Asfakul Islam
然后输出看起来像
Please enter a String: Hello Asfakul Islam
Hello Asfakul Islam
malsI lukafsA olleH
否则,如果您的编译器不支持VLA,则需要动态分配适当大小的数组。在这种情况下,程序可以查找以下方式
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char * reverse_copy( char *s2, const char *s1 )
{
size_t n = strlen( s1 );
size_t i = 0;
for ( ; i < n; i++ ) s2[i] = s1[n-i-1];
s2[i] = '\0';
return s2;
}
int main( void )
{
char s1[1000];
printf( "Please enter a String: " );
fgets( s1, sizeof( s1 ), stdin );
size_t n = strlen( s1 );
if ( n != 0 && s1[n-1] == '\n' ) s1[n-1] = '\0';
char *s2 = malloc( ( n + 1 ) * sizeof( char ) );
puts( s1 );
puts( reverse_copy( s2, s1 ) );
free( s2 );
return 0;
}