C - 我的代码有什么问题(malloc,char *)

时间:2014-11-20 17:29:51

标签: c char malloc reverse

我只是想让你问这个代码我做错了什么。 我写了一个函数,在参数中取一个char *,我想直接修改它而不返回smthg,并反转字符串。

#include <iostream>

void reverseString(char *p_string){

    int length = strlen(p_string);
    int r_it = length - 1;
    char* tmp = (char*)malloc(length);
    int last_it = 0;

    for (int i = 0; i != length; i++){
        tmp[i] = p_string[r_it];
        r_it--;
        last_it++;
    }
    tmp[last_it] = '\0';

    strcpy_s(p_string, length + 1, tmp);
    //free(tmp);
}

int main(){

    char str[] = "StackOverflow";

    reverseString(str);

    std::cout << str << std::endl;

    system("pause");
}

我习惯使用C ++而不经常使用像malloc / free / strcpy这样的C函数... 在这里,我的问题是,当我为我的临时字符分配内存时,我在这种情况下调用了mallec(length)长度= 13,char = 1个字节所以它应该为13个字符分配内存是对的吗?

问题是分配比需要更多的空间,所以我需要在我的strcpy_s之前使用'\ 0',如果没有它会中断。

我在某处犯了错误吗? 此外,当我调用free(tmp)时,它也会断开并说堆损坏,但在此之前我没有释放内存。

感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

我拿了原始代码并在malloc的大小上添加了一个简单的'+1'并获得了传递结果。

不确定您的练习是否与malloc的使用有关,但您是否考虑过直接在原始字符串中进行反转?

例如:

void reverseString(char *p_string){

    char* p_end = p_string+strlen(p_string)-1;
    char t;

    while (p_end > p_string)
    {
        t = *p_end;
        *p_end-- = *p_string;
        *p_string++ = t;
    }
}

int main(){

    char str[] = "StackOverflow";

    reverseString(str);

    std::cout << str << std::endl;

    system("pause");
}

如果您需要使用malloc,那么您需要确保为字符串分配足够的空间,其中包含'\ 0'

答案 1 :(得分:1)

您必须使用

int length = strlen(p_string);
int r_it = length - 1;
char* tmp = (char*)malloc(length+1);

因为strlen不计算\ 0字符。因此,如果您不使用长度+ 1:

,这将失败
tmp[last_it] = '\0';
  

C字符串的长度由终止确定   null-character:C字符串与字符数一样长   在字符串的开头和终止的空字符之间   (不包括终止空字符本身)。   http://www.cplusplus.com/reference/cstring/strlen/

顺便说一下。 C99支持半动态数组。所以你可以试试这个:

char tmp[length+1];

来源: http://en.wikipedia.org/wiki/Variable-length_array

float read_and_process(int n)
{
    float vals[n];

    for (int i = 0; i < n; i++)
        vals[i] = read_val();
    return process(vals, n);
}

答案 2 :(得分:0)

检查以下C代码: 分配给tmp的内存应该是长度+ 1,如下所示,还有许多不必要的变量可以避免。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void reverseString(char *p_string){

   int i;
   int length = strlen(p_string);
   int r_it = length - 1;
   char* tmp = (char*)malloc(length+1);

   for (i = 0; i != length; i++){
      tmp[i] = p_string[r_it--];
   }   
   tmp[i] = '\0';

   strcpy(p_string, tmp);
   return;

}

int main(){

   char str[] = "StackOverflow";

   reverseString(str);

   printf("%s",str);
   return 0;

}

答案 3 :(得分:0)

您的方法没有任何根本性的错误,只是一些细节。由于我不确定您是如何发现sizeof(tmp)为32的,因此我将您的代码修改为下面的代码,其中包含一些printf和一些小的更改:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

void reverseString(char *p_string)
{
  size_t length = strlen(p_string);
  size_t r_it = length - 1;
  char* tmp = (char*)malloc(length+1);
  int last_it = 0;
  size_t i=0;

  printf("strlen(p_string) = %d\n", strlen(p_string));
  printf("Before: strlen(tmp) = %d\n", strlen(tmp));

  for (i = 0; i != length; i++) {
    tmp[i] = p_string[r_it];
    r_it--;
    last_it++;
  }

  tmp[last_it] = '\0';

  printf("After: strlen(tmp) = %d\n", strlen(tmp));

  strcpy(p_string, tmp);

  free(tmp);
}

int main()
{
  char str[] = "StackOverflow";

  reverseString(str);

  printf("%s\n", str);

  return 0;
}

首先,我删除了所有特定于C ++的代码 - 您现在可以使用gcc进行编译。运行此代码会产生以下输出:

sizeof(p_string) = 13
Before: strlen(tmp) = 0
After: strlen(tmp) = 13
wolfrevOkcatS

这是预期的 - strlen基本上计算字节直到它到达\0字符,因此我们第一次使用strlen打印大小时,它返回0,因为我们刚刚分配了内存。正如另一张海报建议的那样,我们必须分配1个额外的字节来将\0存储在我们的新字符串中。

反向完成后,13个字节将被复制到此内存,第二个strlen将返回预期答案。