我仍然可以对第二次调用malloc()的变量调用free()吗?

时间:2018-09-06 00:46:46

标签: c memory malloc

关于系统如何释放内存,我想知道是否将malloc()调用绑定到您为其分配malloc()的初始变量。

例如,我可以执行以下操作:

<!-- how to make members when login "keep me signed in"  and ho to make users 13+ with the date input -->

<?php
if(!empty($_POST["register-user"])) {
    /* Form Required Field Validation */
    foreach($_POST as $key=>$value) {
        if(empty($_POST[$key])) {
        $error_message = "All Fields are required";
        break;
        }
    }
    /* Password Matching Validation */
    if($_POST['password'] != $_POST['confirm_password']){ 
    $error_message = 'Passwords should be same<br>'; 
    }

    /* Email Validation */
    if(!isset($error_message)) {
        if (!filter_var($_POST["userEmail"], FILTER_VALIDATE_EMAIL)) {
        $error_message = "Invalid Email Address";
        }
    }

    /* Validation to check if gender is selected */
    if(!isset($error_message)) {
    if(!isset($_POST["gender"])) {
    $error_message = " All Fields are required";
    }
    }

    /* Validation to check if Terms and Conditions are accepted */
    if(!isset($error_message)) {
        if(!isset($_POST["terms"])) {
        $error_message = "Accept Terms and Conditions to Register";
        }
    }





    if(!isset($error_message)) {
        require_once("dbcontroller.php");
        $db_handle = new DBController();
        $query = "INSERT INTO members (username, firstname, lastname, password, email, gender, dob) VALUES
        ('" . $_POST["userName"] . "', '" . $_POST["firstName"] . "', '" . $_POST["lastName"] . "', '" . md5($_POST["password"]) . "', '" . $_POST["userEmail"] . "', '" . $_POST["gender"] . "' , '" . $_POST["dob"] . "' )";
        $result = $db_handle->insertQuery($query);
        if(!empty($result)) {
            $error_message = "";
            $success_message = "You have registered successfully!";    
            unset($_POST);
        } else {
            $error_message = "Problem in registration. Try Again!";    
        }
    }
}
?>
<html>

<?php 


    include 'C:\wamp64\www\Etego\stylesignup.css';


    ?>


<head>
<title>https://Etego/signup.com</title>
</head>
<body>
<form name="frmRegistration" method="post" action="">
<table border="0" width="500" align="center" class="demo-table">
<?php if(!empty($success_message)) { ?>    
<div class="success-message"><?php if(isset($success_message)) echo $success_message; ?></div>
<?php } ?>
<?php if(!empty($error_message)) { ?>    
<div class="error-message"><?php if(isset($error_message)) echo $error_message; ?></div>
<?php } ?>
<tr>
<td>User Name</td>
<td><input type="text" class="demoInputBox allinsc" name="userName" value="<?php if(isset($_POST['userName'])) echo $_POST['userName']; ?>"></td>
</tr>
<tr>
<td>First Name</td>
<td><input type="text" class="demoInputBox allinsc" name="firstName" value="<?php if(isset($_POST['firstName'])) echo $_POST['firstName']; ?>"></td>
</tr>
<tr>
<td>Last Name</td>
<td><input type="text" class="demoInputBox allinsc" name="lastName" value="<?php if(isset($_POST['lastName'])) echo $_POST['lastName']; ?>"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" class="demoInputBox allinsc" name="password" value=""></td>
</tr>
<tr>
<td>Confirm Password</td>
<td><input type="password" class="demoInputBox allinsc" name="confirm_password" value=""></td>
</tr>
<tr>
<td>Email</td>
<td><input type="text" class="demoInputBox allinsc" name="userEmail" value="<?php if(isset($_POST['userEmail'])) echo $_POST['userEmail']; ?>"></td>
</tr>
        <tr>
<td>Date Of birth</td>
<td><input type="date" value="<?php print(date("YYYY-MM-DD"))?>" class="demoInputBox" name="dob" value="<?php if(isset($_POST['dob'])) echo $_POST['dob']; ?>"></td>
</tr>
<tr>
<td>Gender</td>
<td><input type="radio" name="gender" value="Male" <?php if(isset($_POST['gender']) && $_POST['gender']=="Male") { ?>checked<?php  } ?>> Male
<input type="radio" name="gender" value="Female" <?php if(isset($_POST['gender']) && $_POST['gender']=="Female") { ?>checked<?php  } ?>> Female
    <input type="radio" name="gender" value="not specified" <?php if(isset($_POST['gender']) && $_POST['gender']=="not specified") { ?>checked<?php  } ?>> not specified
</td>
</tr>
<tr>
<td colspan=2>
<input type="checkbox" name="terms"> I accept <a href="terms.html">Terms and Conditions</a> <input type="submit" name="register-user" value="Register" class="btnRegister"></td>
</tr>

</table>
</form>

<div class="header1"></div>
    <div class="hdetail1"></div>

    <h class="etegotxt1">Etego</h>

    <img src="Etego_Logo.png" alt="Etego logo" width="50" height="50" class="logo1">

</body></html>

我打算释放最初分配给ptr1的内存,但后来又由另一个指针释放。

2 个答案:

答案 0 :(得分:11)

让我们逐步进行操作(UNDEF意味着我们不知道值是什么; valid意味着可以安全使用指针):

void *ptr1, *ptr2;    /* ptr1=UNDEF (invalid), ptr2=UNDEF (invalid) */
ptr1 = malloc(50);    /* ptr1=0xAAA (valid),   ptr2=UNDEF (invalid) */
ptr2 = ptr1;          /* ptr1=0xAAA (valid),   ptr2=0xAAA (valid)   */
ptr1 = malloc(25);    /* ptr1=0xBBB (valid),   ptr2=0xAAA (valid)   */
free(ptr2);           /* ptr1=0xBBB (valid),   ptr2=UNDEF (invalid) */

free()不知道将其传递的指针存储在哪个 变量中;它不保证(但也不保证)以任何方式更新或与变量交互。从应用程序开发人员的角度来看,所有有效改变的是实际上使用该指针,还是在返回它的malloc()调用期间对分配的内存块进行任何其他引用是安全的。

@M.M in comments所述,C语言规范明确指出未定义指向已释放对象的指针的值,并且允许编译器以任何方式对其进行修改;请参阅Why does MISRA C state that a copy of pointers can cause a memory exception?进行进一步的讨论。

答案 1 :(得分:2)

简短回答:是

更长的答案:

您不是在变量上调用free,而是在变量中存储的 value 上调用。

为了更好地了解发生了什么,最好将内存视为一个大字节数组,然后将指针可视为该数组中的数字索引。在您可能会遇到的大多数架构上,这实际上是幕后发生的事情。

这样做的时候

void * ptr1 = malloc(50);

malloc正在保留一个50字节的块,并返回一个指向该块的指针。该指针不过是一个数字索引,它告诉我们保留块在内存中的起始位置。

理论上,我们可以(在某些体系结构上)编写

int ptr1 = (int)malloc(50);

我们不这样做的原因是:

  1. sizeof(int)的大小可能不足以容纳指针
  2. void *告诉编译器应该将存储在ptr1中的数值视为一个内存地址。

如果我们继续查看您的代码:

void * ptr2 = ptr1;

这里没有神奇的事情发生。将ptr1中存储的“数值”复制到ptr2中,就像ptr1ptr2是普通整数变量一样。

ptr1 = malloc(25);

在这里,您用新的“数值”覆盖了ptr1的内容,但是旧的值 仍作为副本存在于ptr2中。

free(ptr2);

您在这里用存储在free中的值调用ptr2。这是malloc(50)返回的值。 free不在乎哪个变量保存该值/地址。它只关心值/地址指向由malloc保留的内存块的第一个字节。

从理论上讲,如果您知道malloc(50)返回的值为0xb00b1e5,则可以这样做

free((void *) 0xb00b1e5);

但是您无法安全地预测malloc将返回什么,所以不要这样做。